当你开始写js代码的时候,函数绑定可能是你要考虑的问题,在函数嵌套里面,怎麽处理上下文的this呢?其实你需要考虑的就是
Function.prototype.bind()了。
第一次你遇到这个问题的时候,你可能倾向使用this,但是当上下文引用发送改变的时候,你会使用self,_this或者其他的;当然这并没
有什么大碍,但是可能会有更好解决办法。看个例子:
var myObj = {
specialFunction: function () {
},
anotherSpecialFunction: function () {
},
getAsyncData: function (cb) {
cb();
},
render: function () {
var that = this;
this.getAsyncData(function () {
that.specialFunction();
that.anotherSpecialFunction();
});
}
};
myObj.render();
如果我们this.specialFunction()方式调用函数,那么会报错:
Uncaught TypeError: Object [object global] has no method 'specialFunction'
当callback回调函数被调用的时候,我们需要知道myObj对象引用的上下文。如果使用that.speicalFunction可以解决上下文的引用,并能够正确的执行函数。但是如果使用
Function.prototype.bind可能会有点不同》
我们重写下上面的代码:
render: function () {
this.getAsyncData(function () {
this.specialFunction();
this.anotherSpecialFunction();
}.bind(this));
}
哦,.bind()只是简单的创建了一个新的函数that,当被调用的时候,this关键字就是作为参数被提供的值。所以,当我们传递上下文,this(这里是myObj)到bind()函数的时候,当回调函数被执行,this引用到myObj;
Function.prototype.bind的代码如下:
Function.prototype.bind = function (scope) {
var fn = this;
return function () {
return fn.apply(scope);
};
}
下面是一个简单的例子:
var foo = {
x: 3
}
var bar = function(){
console.log(this.x);
}
bar(); // undefined
var boundFunc = bar.bind(foo);
boundFunc(); // 3
我们创建了一个新的函数that,当执行的时候,this被设置为foo。
但是Function.prototype.bind不被ie8及以下的浏览器所支持。幸运的是,Mozzlia官方网站为我们提供了解决方案:
if (!Function.prototype.bind) {
Function.prototype.bind = function (oThis) {
if (typeof this !== "function") {
// closest thing possible to the ECMAScript 5 internal IsCallable function
throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
}
var aArgs = Array.prototype.slice.call(arguments, 1),
fToBind = this,
fNOP = function () {},
fBound = function () {
return fToBind.apply(this instanceof fNOP && oThis
? this
: oThis,
aArgs.concat(Array.prototype.slice.call(arguments)));
};
fNOP.prototype = this.prototype;
fBound.prototype = new fNOP();
return fBound;
};
}