Function.prototype.bind [英] Function.prototype.bind

查看:96
本文介绍了Function.prototype.bind的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个关于EcmaScript-5 Function.prototype.bind实现的非常有趣的问题。通常当你使用绑定时,你这样做:

  var myFunction = function(){
alert(this );
} .bind(123);

//将提醒123
myFunction();

好吧,这很酷,但是当我们这样做时会发生什么?

  // rebind binded function 
myFunction = myFunction.bind('foobar');
//会提醒... 123!
myFunction();

据我所知,这完全符合Function.prototype.bind实现的逻辑行为( https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind )。但在现实生活中,这完全是无用的行为,不是吗?问题是:它是缺陷还是功能?如果这是一个错误,为什么它没有提到?如果这是一项功能,那么为什么Google Chrome本身的绑定实现的行为方式完全相同?为了更清楚地说明,我认为什么会更有意义,这里是实现Function.prototype.bind的代码片段,它有点不同:

  if(!Function.prototype.bind ){
Function.prototype.bind = function(){
var funcObj = this;
var original = funcObj;
var extraArgs = Array.prototype.slice.call(arguments);
var thisObj = extraArgs.shift();
var func = function(){
var thatObj = thisObj;
return original.apply(thatObj,extraArgs.concat(
Array.prototype.slice.call(
arguments,extraArgs.length

));
};
func.bind = function(){
var args = Array.prototype.slice.call(arguments);
return Function.prototype.bind.apply(funcObj,args);
}
返回func;
};
}

所以现在试试这个:

  // rebind绑定函数
myFunction = myFunction.bind('foobar');
//会提醒...foobar
myFunction();

在我看来,取代this更有意义......



那么你们对此有何看法?

解决方案 先例 Function.prototype.bind 是这个想法在各种JS框架中的实现。据我所知,没有一个人允许这个 -binding被随后的绑定改变。你可能会问,为什么没有人允许这种绑定的变化,至于为什么ES5不允许它。



你不是唯一一个我'已经听过谁认为这很奇怪。克里斯莱里,谁在Mozilla的JS引擎工作(像我一样),认为这有点奇怪,几个月前在Twitter上提出这个问题。我记得其中一个Mozilla实验室黑客质疑是否有某种方法可以解除某个函数,从中提取目标函数。 (如果你可以这样做,你当然可以把它绑定到不同的这个,至少你也可以提取绑定的参数列表来传递它。)



当指定 bind 时,我不记得正在讨论的问题。但是,当这些东西被抛出时,我并没有特别关注es-discuss邮件列表。也就是说,我不相信ES5正在寻求在该地区进行创新,只是铺设一条牛通路,借用一句话。



您可能可以提出一些内省的方法来解决这些问题以进行讨论,如果你写了一个足够详细的提案。另一方面,绑定是信息隐藏机制的一种形式,它会削弱它的采用。如果你有时间,可能值得尝试提出一些建议。我的猜测是信息隐藏的担忧会阻止提案被采纳。但这只是一个猜测,可能是错误的。只有一种方法可以找出...


I've got pretty interesting question about EcmaScript-5 Function.prototype.bind implementation. Usually when you use bind, you do it this way:

var myFunction = function() {
    alert(this);
}.bind(123);

// will alert 123
myFunction();

Okay so that's cool, but what is suppose to happen when we do this?

// rebind binded function
myFunction = myFunction.bind('foobar');
// will alert... 123!
myFunction();

I understand that it's completely logical behavior in terms of how Function.prototype.bind is implemented (https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind). But in real life conditions it's completely useless behavior isn't it? The question is: is it bug or feature? If it's a bug, why it's nowhere mentioned? If it's a feature, why then Google Chrome with native "bind" implementation behaves absolutely the same way?

To make it more clear, what in my opinion would make more sense, here is the code snippet that implements Function.prototype.bind a little bit differently:

if (!Function.prototype.bind) {
    Function.prototype.bind = function() {
        var funcObj = this;
        var original = funcObj;
        var extraArgs = Array.prototype.slice.call(arguments);
        var thisObj = extraArgs.shift();
        var func = function() {
            var thatObj = thisObj;
            return original.apply(thatObj, extraArgs.concat(
                Array.prototype.slice.call(
                    arguments, extraArgs.length
                )
            ));
        };
        func.bind = function() {
            var args = Array.prototype.slice.call(arguments);
            return Function.prototype.bind.apply(funcObj, args);
        }
        return func;
    };
}

So now try this:

// rebind binded function
myFunction = myFunction.bind('foobar');
// will alert... "foobar"
myFunction();

In my opinion, replacing "this" makes more sense...

So what do you guys think about it?

解决方案

The precedent for Function.prototype.bind was the implementation of the idea in various JS frameworks. To the best of my knowledge, none of them allowed this-binding to be changed by subsequent binding. You might as well ask why none of them allowed this-binding changing, as to ask why ES5 doesn't allow it.

You're not the only person I've heard who thought this odd. Chris Leary, who works on Mozilla's JS engine (as I do), thought it a bit odd, raising the issue on Twitter a couple months ago. And in a somewhat different form, I remember one of the Mozilla Labs hackers questioning if there were some way to "unbind" a function, to extract the target function from it. (If you could do that, you could of course bind it to a different this, at least if you could also extract the bound arguments list to also pass it along.)

I don't remember the issue being discussed when bind was being specified. However, I wasn't paying particularly close attention to the es-discuss mailing list at the time this stuff was hashed out. That said, I don't believe ES5 was looking to innovate in the area much, just "pave a cowpath", to borrow a phrase.

You might possibly be able to propose some introspective methods to address these concerns to es-discuss, if you wrote a sufficiently detailed proposal. On the other hand, binding is a form of information-hiding mechanism, which would cut against its adoption. It might be worth a try to propose something, if you have time. My guess is the information-hiding concern would block a proposal from being adopted. But that's just a guess that could well be wrong. Only one way to find out...

这篇关于Function.prototype.bind的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆