bind()方法会创建一个新函数,称为绑定函数。当调用这个绑定函数时,绑定函数会以创建它时传入bind()方法的第一个参数作为 this
,传入 bind() 方法的第二个以及以后的参数加上绑定函数运行时本身的参数按照顺序作为原函数的参数来调用原函数。
实际使用中我们经常会碰到这样的问题:
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
这个时候输出的this.nickname
是undefined,原因是this
指向是在运行函数时确定的,而不是定义函数时候确定的,再因为setTimeout在全局环境下执行,所以this
指向setTimeout
的上下文:window
。
以前解决这个问题的办法通常是缓存this
,例如:
function Person(name){ this.nickname = name; this.distractedGreeting = function() { var self = this; // <-- 注意这一行! setTimeout(function(){ console.log("Hello, my name is " + self.nickname); // <-- 还有这一行! }, 500); } } var alice = new Person('Alice'); alice.distractedGreeting(); // after 500ms logs "Hello, my name is Alice"
这样就解决了这个问题,非常方便,因为它使得setTimeout
函数中可以访问Person的上下文。但是看起来稍微一种蛋蛋的忧伤。
但是现在有一个更好的办法!您可以使用bind。上面的例子中被更新为:
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"
bind() 最简单的用法是创建一个函数,使这个函数不论怎么调用都有同样的
this
值。JavaScript新手经常犯的一个错误是将一个方法从对象中拿出来,然后再调用,希望方法中的 this
是原来的对象。(比如在回调中传入这个方法。)如果不做特殊处理的话,一般会丢失原来的对象。从原来的函数和原来的对象创建一个绑定函数,则能很漂亮地解决这个问题:
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
引自:http://www.css88.com/archives/5611