注意:
this
是在函数被调用的时候发生的绑定,它指向什么彻底取决于在哪里被调用。javascript
在严格和非严格模式下,this
的指向有所不一样java
function f1() {
return this;
}
// In a browser:
f1() === window; // true
// In Node:
f1() === global; // true
//严格模式以下:
function f2() {
'use strict'; // see strict mode
return this;
}
f2() === undefined; // true
复制代码
那么在函数在执行过程当中调用位置如何决定this的绑定对象? 有四条规则app
就是,经常使用的函数调用。函数
如上f一、f2
函数的调用,都采用【默认绑定】。绑定到全局对象window
或者global
上。oop
就是,对象的方法调用。若是说函数的调用位置有上下文对象,或者说被某个对象拥有或者包 含,那就是隐式绑定。ui
function foo() {
console.log( this.a );//this指向obj对象
}
var obj = {
a: 2,
foo: foo
};
obj.foo(); // 2
var obj1 =
复制代码
当含有this
的方法赋值给变量,而后被调用时,会发生隐式丢失,即丢失了绑定的对象。 例如:this
function foo() {
console.log(this.a);
}
var obj = {
a: 2,
foo: foo
};
var bar = obj.foo; // 函数别名!
var a = "oops, global"; // a 是全局对象的属性
bar(); // "oops, global"
复制代码
foo
函数隐式绑定了obj
对象,在赋值给变量bar
后,被调用打印this.a
结果是全局变量a
的值。 隐式绑定丢失所绑定的对象后,采用默认的绑定方式,this
执行全局环境spa
当含有this
的方法应用于回调函数时,也会发生隐式丢失。 没错,这种状况一样也发生在回调函数,类比“赋值给变量”。.net
function foo() {
console.log(this.a);
}
var obj = {
a: 2,
foo: foo
};
var a = "oops, global"; // a 是全局对象的属性
setTimeout( obj.foo, 100 );//oops,global
复制代码
那么,上述遇到的隐式丢失该如何解决呢?这就须要说到下一个规则【显示绑定】code
能够在某个对象上强制调用函数。或者说改变this的指向 不得不说call
、apply
、bind
三个函数
这三个方法能够解决如上【隐式丢失】的问题。
使用new
来调用函数,或者说发生构造函数调用,则会自执行以下操做:
[[原型]]
链接this
上this
,也就是这个新对象。注意,第4点。默认返回this
,也就是说能够返回其余对象。好比:
function Man(name) {
console.log('man', this);
this.name = name;
return {}; //函数有本身的返回对象
}
function Woman(name) {
console.log('woman:', this);
this.name = name;
}
var man = new Man('Davin');
console.log(man) // {}
var woman = new Woman('Lisa');
console.log(woman) //{name: "Lisa"}
复制代码
在箭头函数中,this
与封闭词法环境的this
保持一致。在全局代码中,它将被设置为全局对象。
var globalObject = this;
var foo = (() => this);
console.log(foo() === globalObject); // true
复制代码
不管如何,foo
的 this
被设置为他被建立时的环境(在上面的例子中,就是全局对象)。这一样适用于在其余函数内建立的箭头函数:这些箭头函数的this
被设置为封闭的词法环境
的。以下:
// 做为对象的一个方法调用
var obj = {foo: foo};
console.log(obj.foo() === globalObject); // true
// 尝试使用call来设定this
console.log(foo.call(obj) === globalObject); // true
// 尝试使用bind来设定this
foo = foo.bind(obj);
console.log(foo() === globalObject); // true
复制代码
箭头函数中this的指向并未发生变化。
参考阅读 《你不知道的JavaScript(上)》 MDN 之 this 透彻理解并掌握JavaScript的this