简介
对于一个给定的函数,创造一个绑定对象的新函数,这个函数和之前的函数功能一样,this值是它的第一个参数,其它参数,作为新的函数的给定参数。
bind的作用
bind最直接的作用就是改变this的指向
// 定义函数 var checkNumericRange = function (value) { if (typeof value !== 'number') return false; else return value >= this.minimum && value <= this.maximum; } // 定义对象 var range = { minimum: 10, maximum: 20 };
这时就会碰到一个问题,因为作用域不符,checkNumricRange不能操作range对象的属性。
那我们该如何做呢?
答案是修改this的值。把函数内部的this修改为range对象,这样这个函数就可以访问range的属性。
通过bind可以很好的实现。
// 限定函数的this值为range,返回一个新的函数 var boundCheckNumericRange = checkNumericRange.bind(range); // 使用新生成的函数。 var result = boundCheckNumericRange (12); document.write(result);// true
让我们分析分析checkNumricRange.bind(range)都做了什么?
通过bind方法,将this的值修改为range对象,返回一个新函数,这个函数this值是range,但函数的功能没有改变。
Function.prototype.bind原理解析
内部原理有一点点绕人,
下面给出一个简化的bind代码,
Function.prototype.bind = function (scope) { var fn = this;//这里fn为this,也就是调用bind的函数,方便下面调用 return function () {//返回的是一个可以运行函数 return fn.apply(scope);//利用apply方法,使用scope对象调用fn, }; }
一个简单的测试用例
var foo = { x: 3 } var bar = function(){ console.log(this.x); } bar(); // undefined var boundFunc = bar.bind(foo); boundFunc(); // 3
具体适用情况
1.在事件监听时,简化在触发事件时用匿名函数的情况
这是一个用来处理和保存数据的计数器
var logger = { x: 0, updateCount: function(){this.x++; console.log(this.x); } }
一般经常使用以下情况去运行方法updateCount,
添加一个匿名函数,然后用logger对象调用方法updateCount,以保证updateCount里可以通过this访问logger.
document.getElementsByTagName("button")[0].addEventListener("click",function(){ logger.updateCount(); })
但是现在我们可以是用bind简化这个内容。
document.getElementsByTagName("button")[0].addEventListener("click",logger.updateCount.bind(logger))