Function.prototype.bind分析
bind()方法会创建一个新的函数,成为绑定函数。当调用这个绑定函数时,绑定函数会以创建它时传入的第一个参数作为this,传入bind()方法的第二个以及以后的参数加上绑定函数运行时本身的参数按照顺序作为原函数的参数来调取原函数。
实际使用中我们经常会碰到这样的问题:
var name = "pig";function Person(name){ this.name = name; this.getName = function(){ setTimeout(function(){ console.log("Hello,my name is "+this.name); },100); }}var weiqi = new Person("卫旗");weiqi.getName(); //Hello,my name is pig
这个时候输出this.name是pig,原因是this的指向是在运行函数时确定的,而不是在定义函数时确定的,再因为setTimeout是在全局环境下只想,所以this就指向了window。
以前解决这个问题的办法通常是缓存this,例如:
var name = "pig";function Person(name){ this.name = name; this.getName = function(){ //在这里缓存一个this var self = this; setTimeout(function(){ //在这里是有缓存this的self console.log("Hello,my name is "+self.name); },100); }}var weiqi = new Person("卫旗");weiqi.getName();//Hello,my name is 卫旗
这样就解决了这个问题,非常方便,因为它使得setTimeout函数中可以访问Person的上下文。
现在有一个更好的解决办法,可以使用bind()函数,上面的例子可以被更新为:
var name = "pig";function Person(name){ this.name = name; this.getName = function(){ setTimeout(function(){ console.log("Hello,my name is "+this.name); }.bind(this),100); //注意上面这一行,添加了bind(this) }}var weiqi = new Person("卫旗");weiqi.getName();//Hello,my name is 卫旗
bind()最简单的用法是创建一个函数,使得这个函数无论怎么样调用都拥有同样的this值。JavaScript新手经常犯的一个错误就是将一个方法从一个对象中拿出来,然后再调用,希望方法中的this是原来的对象(比如在回调函数中传入这个方法)。如果不做特殊处理的话,一般会丢失原来的对象。从原来的函数和原来的对象创建一个绑定函数,则可以很漂亮的解决这个问题:
//定义全局变量xvar x = "window";//在module内部定义xvar module = { x:"module", getX:function(){ console.log(this.x); }}module.getX(); //返回module,因为在module内部调用getX()var getX = module.getX;getX();//返回window,因为这个getX()是在全局作用域中调用的//绑定getX()并将this值设为modulevar boundGetX = getX.bind(module);boundGetX();//返回module,绑定以后this值始终为module
新闻热点
疑难解答
图片精选