在我最近的编码中,我发现了一个更简单的方法。在这个过程中,它消除了匿名函数并删除了linting错误,“不要在循环中写函数”。
你看,我一直在使用JavaScript中的bind()试验。事实证明,我们可以在多个场合,包括处理我几周前提到的闭包问题中,使用bind。
bind函数最近才添加到JavaScript的规范说明中,所以它只能工作于最新的浏览器上。你可以查看兼容性表看看哪些浏览器实现bind()以及其他JavaScript功能。我仔细地看了看名单,我关注的浏览器没有不支持bind()的。当然你的情况可能会有所不同。
bind所做的就是自动封装函数在函数自己的闭包中,这样我们可以捆绑上下文(this关键字)和一系列参数到原来的函数。
你最终得到的是另一个函数指针。
function add(a,b){
return a + b;
}
var newFoo = add.bind(this,3,4);
请注意,我们不仅捆绑this到foo()函数,而且我们也捆绑了两个参数。所以,当我们调用newFoo()的时候,返回值将是7。
但是,如果我们在调用之前newFoo更改的参数的话,会发生什么?
如果我们使用变量绑定参数到foo(),然后在调用newFoo()前改变变量,你觉得值会变为什么呢?
function add(a,b){
return a + b;
}
var a = 3;
var b = 4;
var newFoo = add.bind(this,a, b);
a = 6;
b = 7;
console.log(newFoo());
返回值仍然是7,因为bind()绑定的是参数的值,而不是实际变量的值。
这是好消息,就像我说的,我们可以在代码中利用这个巨大的优势。但是,对我而言它最有用的地方是在callbacks中。
还记得那篇文章中我们在循环中处理callbacks的解决方案之一就是,围绕我们想要调用的函数创建匿名函数。
for(var i = 0;i < 10;i++){
(function(ii){
setTimeout(function(){
console.log(ii);
},1000);
})(i);
但是我们可以使用bind,大大简化代码。
function consoleLog(i){
console.log(i);
}
for(var i = 0;i < 10;i++){
setTimeout(consoleLog.bind(this,i),1000);
}
这是因为每次调用bind就会给出一个新的函数指针,并且保留原来的函数不变。
同时,我们还删除了linting错误“不要在循环写函数”,因为我们不是在循环中创造的函数,我们只是指向了我们在循环外创建的函数。
bind()可以让你的代码干净起来的另一个地方是在事件处理程序。大家都知道,或者应该知道,当一个事件处理程序被调用时,它访问的上下文会生成事件,而不是在创建事件处理程序的对象中。通过使用bind,可以肯定的是,函数会被访问正确的上下文。
function ClassName(){
this.eventHandler = (function(){
}).bind(this);
}
不是说你要像那样写代码,这只是为了说明要点。
什么?!
OK。我会是第一个承认,自己的函数式编程知识是有限的。我能给出的关于Currying的最佳定义是,它允许你在多个步骤中传递参数。
使用bind,我们就可以像这样写代码实现Currying:
function add(a,b,c) {
return a+b+c;
}
var addAgain = add.bind(this, 1, 2);
var result = addAgain(3);
bind() 方法创建一个新的函数,在 bind() 被调用时,这个新函数的 this 被bind的第一个参数指定,其余的参数将作为新函数的参数供调用时使用。那bind创建的这个新函数还有其他什么特性吗?
这些API的特点以及具体用法我就不介绍了,相信你如果奔着手动实现的方向来看,那么你一定对它很了解,核心: this永远指向最后调用它的对象
sayColor() 调用 bind() 并传入对象 o ,创建了 o bjectSayColor() 函数。 object-SayColor() 函数的 this 值等于 o ,因此即使是在全局作用域中调用这个函数,bind与apply、call最大的区别就是:bind不会立即调用
bind 和 apply,call 是 JS 修改 this 指向的三把利器 。对于 apply,call 来说,bind 的区别在于会返回一个修改了 this 指向的新函数,并不会立即执行。
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!