我是靠谱客的博主 复杂背包,最近开发中收集的这篇文章主要介绍javaScript中this的指向,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

javaScript中this的指向

非箭头函数

this => 调用其所在函数对象,而且距离谁近指向谁(常规对象,原型链,getter & setter都适用);

构造函数

this => 被新创建的对象

DOM事件

this => 触发事件的元素

内联事件

bind/call & apply

全局环境

在全局环境下,this 始终指向全局对象(window), 无论是否严格模式;

console.log(this.document === document); // true
// 在浏览器中,全局对象为 window 对象:
console.log(this === window); // true
this.a = 37;
console.log(window.a); // 37

函数上下文调用

函数直接调用

普通函数内部this分两种情况 严格模式和非严格模式

非严格模式下 this指向 window 对象

function f1() {
return this
}
console.log(f1 === window); // true

严格模式下 this为 undefind

 function f2() {
'use strict' // 严格模式
return this
}
console.log(f2() === undefind); // true

Object 中的this

对象内部方法的this指向调用这些方法的对象

  1. 定义函数的位置和this没有关系,只和调用函数的对象有关。
  2. 多层嵌套的对象,内部函数调用的this指向调用函数最近的对象(window也是对象,其内部对象调用方法的this指向内部对象,非window对象)。
var Obj = {
name: 'Mary',
age: 20,
getName: function () {
return this.name
}
}
console.log(Obj.getName()); // Mary
this 指向 Obj(最近的)
var f3 = Obj.getName;
console.log(f3()); // undefind this 指向 f3(最近的) 非 Obj
function Age() {
return this.age
}
Obj.getAge = Age;
console.log(Obj.getAge()); // 20
this 指向 Obj(最近的)
Obj.prop = {
getAge: Age,
age: 30
}
console.log(Obj.prop.getAge()); // 30 this 指向 Obj.prop(最近的) 非 Obj

原型链中this

原型链中方法的this同样指向调用它的对象

var Obj = {
Todo: function() {
return this.a + this.b
}
}
var P = Object.create(Obj);
P.a = 2;
P.b = 3;
console.log(P.Todo()); // 5 this 指向 P 调用方法的对象(最近的)

由此可见 P 中没有 Todo 方法,但是执行 P.Todo 时,会查找P的原型链,找到 Todo 函数并执行,但这与内部this指向P没有任何关系,
和调用函数的对象有关系。

getter & setter

同上所述

构造函数中的 this

构造函数的 this 与新创建的对象绑定

注:当构造器返回的默认值是 this 引用的一个对象时,可手动设置返回其他对象。
如果返回值不是一个对象,则返回 this。

function C1() {
this.name = 'Mary';
}
var P1 = new C1();
console.log(P1.name); // Mary 返回值不是对象 而是this
function C2() {
this.name = 'Mary';
return {
name: 'Tom'
}
}
var P2 = new C2();
console.log(P2.name); // Tom 返回值是一个对象
可手动更改
this.name = 'Mary' 被忽略

call && apply

当函数通过 Function 原型中继承的 call() & apply() 方法时,其函数内部的 this 可绑定到 call() & apply() 方法指定的第一个对象上,
如果第一个参数不是 Object,JavaScript内部会尝试将其转换成 Object 然后指向它。

function Add(c, d) {
console.log(this);
return this.a + this.b + c + d
}
var obj = {a: 5, b: 9};
Add.call(obj, 6, 8);
//
{a: 5, b: 9} 
Add.apply(obj, [7, 9]); //
{a: 5, b: 9}
function Cost() {
console.log(this)
}
Cost.call(7);
// Number {[[PrimitiveValue]]: 5} 
Cost('222');
// STring {[[PrimitiveValue]]: '222'}
Cost.apply(7);
// Number {[[PrimitiveValue]]: 5} 
Cost.apply([7]);
// [7]

bind 方法

Function.prototype.bind

通过 bind 方法绑定后,函数被永远绑定在第一个参数对象上,被一直调用。

function todo() {
return this.name
}
var Foo = todo.bind({name: 'Mary'});
console.log(Foo()); // Mary
var Bar = {
name: 'Tom',
age: 20,
getName: todo
}
console.log(Bar.getName()); // Tom 同 Object 中的 this

setTimeout & setInterval

延时函数内部 this 指向 window 对象,可以使用 bind 改变其 this 指向。

function Person1() {
this.age = '20';
setTimeout(function() {
console.log(this)
},1000)
}
var P1 = new Person1(); // 1s 后输出 window 对象
function Person2(age) {
this.age = age;
setTimeout(function() {
console.log(this)
},1000).bind(this)
}
var P2 = new Person2(20);
// 1s 后输出 P2 (新生成的 Person2 对象)

箭头函数中的 this

方法内部箭头函数,非方法方式调用

注:箭头函数没有定义this绑定,它会捕获其所在(即定义的位置)上下文的this值, 作为自己的this值。

  1. call() & apply() & bind() 只是传入参数,对 this 没有影响。
  2. 考虑到 this 是词法层面上的,严格模式中与 this 相关的规则都将被忽略。(可以忽略是否在严格模式下的影响)

因为箭头函数可以捕获其所在上下文的this值,所以

function Person1() {
this.age = 10;
setTimeout(() => {
console.log(this)
},1000)
}
var P1 = new Person1(); // 1s 后输出 P1 (新生成的 Person1 对象)
function Person2() {
this.age = '20';
setTimeout(function() {
console.log(this)
},1000)
}
var P2 = new Person1(); // 1s 后输出 window 对象

使用箭头函数,this 指向上下文的 this, 而普通函数则指向 window 对象.

** Object 中的箭头函数 **

var People = {
firstName: 'Mary',
getName: function(lastName) {
var f1 = str => `${this.firstName} ${str}`;
return f1(lastName)
},
getFullName: function isFull(lastName) {
var f2 = str => `${this.firstName} ${str}`;
var auther = {
firstName: 'Tom'
};
return f2.call(auther, lastName)
}
}
console.log(People.getName('Mr'));
// Mary Mr this 指向 People 
console.log(People.getFullName('Mr'));
// Mary Mr this 仍然指向 People,没有因为 call 而改变。 

严格模式和非严格模式对比

var f1 = () => {
'use strict';
return this
}
var f2 = () => {
return this
}
console.log(f1());
// window 对象
console.log(f2());
// window 对象
console.log(f1() === f2());
// true
因为都是 window 对象

箭头函数作为方法调用

var obj = {
i: 10,
b: () => {
console.log(this.i, this)
},
c: function () {
console.log(this.i, this)
}
}
obj.b(); // undefind
window 对象
(注:箭头函数没有定义this绑定)
obj.c(); // 10
对象 obj
(注:函数最近的对象)
var fun = obj.c;
fun();
// undefind
window 对象
(注:调用最近的对象 fun 非 obj)

DOM 中的 this

case1:
<button onclick="console.log('1:', this)">1</button>
// 1: <button οnclick="console.log('1:', this)">1</button> (注:this 指向该元素)
case2:
html
<button onclick="handleClick2()">2</button>
js
function handleClick2(){
// 非严格模式
console.log('2:', this)
// 2: window 
}
case3:
html
<button onclick="handleClick3()">3</button>
js
function handleClick3(){
"use strict";
// 严格模式
console.log('3:', this)
// 3: undefind
}
case4:
html
// error 格式
此写法是不允许的 
<button onclick="() => handleClick4()">4</button>

最后

以上就是复杂背包为你收集整理的javaScript中this的指向的全部内容,希望文章能够帮你解决javaScript中this的指向所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(37)

评论列表共有 0 条评论

立即
投稿
返回
顶部