YDNJS(上卷):this 的绑定对象

函数中的 this 是在调用时被绑定的,this 指向谁完全取决于函数的调用位置。

确定 this 的绑定对象的方式有 4 种。

默认绑定

默认绑定就是将函数中的 this 绑定给了全局对象 window。这往往适用于我们调用函数时,不带有任何修饰的情况。

function foo() {
	console.log(this.a);
}

var a = 2;

foo(); // 2

我们调用函数 foo 的方式是直接调用,所以函数执行时,函数中的 this 是指向全局对象 window, 取 window 对象的 a 属性,就是取全局变量 a,所以打印出的结果是 2。

隐式绑定

隐式绑定就是将函数作为对象属性调用。这时函数内部的 this 指向对象本身。

function foo() {
	console.log(this.a);
}

var obj = {
	a: 2,
	foo: foo
};

obj.foo(); // 2

上面的代码中,我们以 obj 对象的属性形式,调用了 foo 函数,这时函数中的 this 就是对象 objthis.a 就是 obj.a,自然就是 2 了。

还有,对于隐式绑定,函数的调用位置是 对象属性引用链中的最后一层

function foo() {
	console.log(this.a);
}

var obj2 = {
	a: 42,
	foo: foo
};

var obj1 = {
	a: 2,
	obj2: obj2
};

obj1.obj2.foo(); // 42

对象属性引用链中的最后一层是 obj2foo 是它的一个属性,所以 foo 函数执行时,内部 this 指向 obj2 对象,所以打印结果是 42。

显式绑定

显示绑定就是使用函数的 call() 或者 apply() 方法,为执行的函数显式指定上下文执行对象,也就是显式指定执行函数内部的 this 指向的对象。

函数的 call() 或者 apply() 方法接收的第一个参数是一个对象,在调用函数时会将这个对象绑定给 this。就是说是直接给 this 指定绑定的对象,因此称为显式绑定。

function foo() {
	console.log(this.a);
}

var obj = {
	a: 2
};

foo.call(obj); // 2

new 绑定

在传统的面向类的语言中,「构造函数」是类中的一个特殊方法,在使用 new 初始化类实例时会被自动调用。

需要清楚得是:JavaScript 中 new 的机制与面向类的语言中的 new 完全不同

在 JavaScript 中,根本就不存在「构造函数」,只有对函数的「构造调用」。JavaScript 中的所有函数都可以用 new 调用,这种函数调用称为对函数的「构造调用」。

使用 new 来调用函数,或者说在对函数进行「构造调用」时,会自动执行下列步骤:

  1. 创建一个全新的对象。
  2. 新对象执行 [[Prototype]] 连接。
  3. 被调用函数中的 this 绑定到这个新对象。
  4. 如果函数没有返回其他对象,则返回这个新对象。

下面是一个例子:

function foo() {
	this.a = a;
}

var bar = new foo(2);

bar.a; // 2

我们使用 new 来调用 foo() 时,会创建一个全新的对象,然后 foo 函数内部的 this 就会绑定到这个新对象上。

优先级

new 绑定 > 显式绑定 > 隐式绑定 > 默认绑定

posted @ 2017-09-28 12:38  Hi!张宝  阅读(190)  评论(1编辑  收藏  举报