在Javascript中,Function是一种对象。Function对象中的this指向决定于函数被挪用的体式格局。
这是我们就须要用到这三个小家伙了:call、apply、bind来转变this的指向。
先来谈谈我们所熟知的call和apply
function add(c, d){
return this.a + this.b + c + d;
}
var o = {a:1, b:2};
add.call(o, 3, 4); // 10
add.apply(o, [5, 6]); // 14
须要注重的是,假如传入的第一个参数不是对象范例的,那末这个参数会被自动转化为对象范例,比方:
function age() {
console.log(
Object.prototype.toString.call(this)
);
}
bar.call(7); // [object Number]
接下来讲一下bind
ECMAScript 5引入了Function.prototype.bind。挪用f.bind(someObject)会发生一个新的函数对象。在这个新的函数对象中,this被永远绑定到了bind的第一个参数上面,不管后期这个新的函数被怎样运用。
function f(){
return this.a;
}
var g = f.bind({a:"jack"});
console.log(g()); // jack
var o = {a:37, f:f, g:g};
console.log(o.f(), o.g()); // 37, jack
function Person(name){
this.nickname = name;
this.distractedGreeting = function() {
setTimeout(function(){
console.log("Hello, my name is " + this.nickname);
}, 500);
}
}
var alice = new Person('Alice');
alice.distractedGreeting();
//Hello, my name is undefined
function Person(name){
this.nickname = name;
this.distractedGreeting = function() {
setTimeout(function(){
console.log("Hello, my name is " + this.nickname);
}.bind(this), 500); // <-- this line!
}
}
var alice = new Person('Alice');
alice.distractedGreeting();
// after 500ms logs "Hello, my name is Alice"
this.x = 9;
var module = {
x: 81,
getX: function() { return this.x; }
};
module.getX(); // 81
var getX = module.getX;
getX(); // 9, 由于在这个例子中,"this"指向全局对象
// 建立一个'this'绑定到module的函数
var boundGetX = getX.bind(module);
boundGetX(); // 81
别的,假如第一个参数为null或许undefined的话,那末,实际上绑定到的是全局对象,即global。这一点对三者都实用。
function age() {
console.log(
Object.prototype.toString.call(this)
);
}
bar.bind()(); // [object global]
bar.apply(); // [object global]
bar.call(); // [object global]