怎么改变this的指向

call和apply的作用都是在函数运行时指定this值,注意:指定的this值并不一定是该函数执行时真正的this值,如果这个函数处于非严格模式下,则指定为null和undefined的this值会自动指向全局对象(浏览器中就是window对象),同时值为原始值(数字,字符串,布尔值)的this会指向该原始值的自动包装对象

1. 使用call改变this的指向

call() 方法调用一个函数, 其具有一个指定的this值和分别地提供的参数(参数的列表)。

1
2
3
4
5
6
7
8
9
function add(c, d) {
return this.a + this.b + c + d;
}

var o = {a: 1, b: 3};

// 第一个参数是作为this使用的对象
// 后续参数作为参数传递给函数调用
add.call(o, 5, 7); // 1 + 3 + 5 + 7 = 16

2. 使用apply改变this的指向

apply() 方法调用一个函数, 其具有一个指定的this值,以及作为一个数组(或类似数组的对象)提供的参数。

1
2
3
4
5
6
7
8
9
function add(c, d) {
return this.a + this.b + c + d;
}

var o = {a: 1, b: 3};

// 第一个参数也是作为this使用的对象
// 第二个参数是一个数组,数组里的元素用作函数调用中的参数
add.apply(o, [10, 20]); // 1 + 3 + 10 + 20 = 34

3. 使用bind改变this指向

bind() 函数会创建一个新函数(称为绑定函数),新函数与被调函数(绑定函数的目标函数)具有相同的函数体(在 ECMAScript 5 规范中内置的call属性)。当新函数被调用时 this 值绑定到 bind() 的第一个参数,该参数不能被重写。绑定函数被调用时,bind() 也接受预设的参数提供给原函数。一个绑定函数也能使用new操作符创建对象:这种行为就像把原函数当成构造器。提供的 this 值被忽略,同时调用时的参数被提供给模拟函数。

1
2
3
4
5
6
7
8
9
10
11
12
var module = {
x: 42,
getX: function() {
return this.x;
}
}

var unboundGetX = module.getX;
console.log(unboundGetX()); // The function gets invoked at the global scope expected output: undefined

var boundGetX = unboundGetX.bind(module);
console.log(boundGetX()); // expected output: 42