我对this的理解(JavaScript)

注意: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的指向 不得不说callapplybind三个函数

这三个方法能够解决如上【隐式丢失】的问题。

new绑定

使用new来调用函数,或者说发生构造函数调用,则会自执行以下操做:

  1. 建立一个全新的对象
  2. 这个新对象会被执行[[原型]]链接
  3. 这个新对象会绑定到函数调用的this
  4. 若是函数没有返回其余对象,则会默认返回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
复制代码

不管如何,foothis被设置为他被建立时的环境(在上面的例子中,就是全局对象)。这一样适用于在其余函数内建立的箭头函数:这些箭头函数的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

相关文章
相关标签/搜索