理解js中的this
程序员文章站
2022-03-29 17:51:58
...
this是javascript中的关键字,this在运行的时候决定而不是在作者编写函数(author-time)的时候决定。
因此理解this的最好方式,是查看调用栈(call stack),找到调用位置(call-site),就总体而言,this指向的是调用该函数的对象。
四种情况:
一、默认绑定(default binding)--作为函数调用
再次明确,this指向的是调用该函数的对象。下面的函数foo在调用的时候实际上相当于global.foo(),这里global是window对象,this.a指的是window对象中定义的a,而不是函数foo内部定义的a,因此输出值为2而不是3.
function foo() {
var a = 3;
console.log( this.a );
}
var a = 2;
foo(); // 2
二、隐式绑定(Implicit Binding)---作为对象属性
既然作为对象的属性,自然也就是该对象调用该函数,this指向这里的obj。
function foo() {
console.log( this.a );
}
var obj = {
a: 2,
foo: foo
};
var a = 3;
obj.foo(); // 2
这里值得注意的是this的隐式丢失(Implicitly lost)问题
下面的bar变成了一个foo函数指针,在调用的时候相当于global.bar()
function foo() {
console.log( this.a );
}
var obj = {
a: 2,
foo: foo
};
var bar = obj.foo; // 变成普通的函数调用
var a = 3; // "a"是global对象的一个属性。
bar()//3
如果存在一个对象链条呢?看最近的那个调用对象
三、显式绑定(Explicit Binding)---call和apply
function foo() {
console.log( this.a );
}
var obj2 = {
a: 42,
foo: foo
};
var obj1 = {
a: 2,
obj2: obj2
};
obj1.obj2.foo(); // 42
这里指的是用call和apply来强制绑定调用对象。
function foo() {
console.log( this.a );
}
var obj = {
a: 2
};
foo.call( obj ); // 2
书中还提到一种hard-binding,顾名思义,就是直接把把函数调用对象直接绑死了,使得在运行的难以修改,根据上面的“就近原则”,obj永远是最近的那个调用对象,bar.call(window)相当于window.obj.foo()。
function foo() {
console.log( this.a );
}
var obj = {
a: 2
};
var bar = function() {
foo.call( obj );
};
bar(); // 2
setTimeout( bar, 100 ); // 2
// hard-bound `bar` can no longer have its `this` overridden
bar.call( window ); // 2
四、创建对象绑定(new Binding)----new创建新对象
用new创建对象,this指向的是新创建出来的对象。
function Foo(name){
this.name = name;
}
var a = new Foo("Allen");
a.name;//"Allen"
上一篇: Max Points on a Line
下一篇: js中this的理解