Function.prototype.bind
Function.prototype.bind
我有一个关于EcmaScript-5 Function.prototype.bind实现的非常有趣的问题。通常当你使用bind时,你这样做:
var myFunction = function() {
alert(this);
}.bind(123);
// will alert 123
myFunction();
这很酷,但是当我们这样做的时候会发生什么呢?
// rebind binded function
myFunction = myFunction.bind('foobar');
// will alert... 123!
myFunction();
我理解,就Function.prototype.bind的实现方式而言,这是完全合乎逻辑的行为(https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind)。但在现实生活中,这是完全无用的行为,不是吗?问题是:这是bug还是特性?如果是bug,为什么没人提?如果这是一个功能,为什么谷歌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);
}
return func;
};
}
那么现在试试这个:
// rebind binded function
myFunction = myFunction.bind('foobar');
// will alert... "foobar"
myFunction();
在我看来,替换"this"更有意义…
你们怎么看?
Function.prototype.bind
的先例是在各种JS框架中实现这个想法。据我所知,它们都不允许this
绑定被后续绑定所改变。你可能会问为什么它们都不允许更改绑定,就像问为什么ES5不允许一样。
this
,至少如果你也可以提取绑定的参数列表来传递它。)
我不记得在指定bind
时讨论过这个问题。然而,当这些东西被讨论出来的时候,我并没有特别关注es- discussion邮件列表。也就是说,我不认为ES5在这个领域有太多的创新,借用一句短语,只是"铺路"。
如果你写了一份足够详细的提案,你也许可以提出一些内省的方法来解决这些问题。另一方面,绑定是一种信息隐藏机制,这不利于它的采用。如果你有时间的话,不妨试着提点建议。我的猜测是信息隐藏的顾虑会阻碍提案被采纳。但这只是一个猜测,很可能是错误的。
当你绑定一个函数时,你要求一个新的函数忽略它自己的this伪参数,并使用this的固定值调用原始函数。
下次绑定该函数具有完全相同的行为。如果bind要以某种方式在其中添加一个新的this,则必须对已经绑定的函数进行特殊处理。
换句话说,bind对"普通"函数的作用与对bind返回的函数的作用完全相同,并且在没有覆盖因素的情况下,保持函数的语义复杂性是很好的工程——如果以完全相同的方式处理所有输入函数,而不是特殊处理某些输入函数,则更容易记住bind对函数的作用。
我认为你的困惑是,你认为绑定是修改一个现有的函数,因此,如果你再次修改它,你期望原始函数再次被修改。然而,bind并不修改任何东西,它创建了一个具有特定行为的新函数。新函数本身就是一个函数,它不是对原函数的一个神奇的补丁版本。
因此,它被标准化或被发明的原因并不神秘:bind返回一个提供新的this和前置参数的函数,并且在所有函数上都是一样的。最简单的语义。 只有这样使用才是安全的——如果绑定会使已经绑定的函数和"正常"的函数产生差异,那么必须在绑定之前进行测试。jQuery就是一个很好的例子。每个,它传递一个新的this。如果bind会对绑定函数进行特殊处理,那么将绑定函数传递给jQuery就没有安全的方法了。每个,因为这将在每次调用时被覆盖。为了解决这个问题,使用jQuery。每个函数都必须对绑定函数进行特殊处理。- 直接在函数声明上使用function.prototype.bind
- requestAnimationFrame的Function.prototype.bind导致属性不可读
- Snippet usefulness - Function.prototype.call.bind(Function.p
- 使用 Function.prototype.bind.apply(Obj, args) 将参数传递给对象,只传递第一个元
- Function.prototype.call.bind 是如何工作的
- 使用 Function.prototype.bind 或保存的引用
- Phantomjs Function.prototype.bind
- Function.prototype.bind with null 作为参数
- Mootools 何时使用 Function.prototype.bind
- Javascript: argument unpacking in function.prototype.bind()?
- 为什么使用Function.prototype.bind.apply
- JavaScript'有Ruby等价物吗;s函数.prototype.bind
- Array.prototype.map.bind与对象一起使用是否可靠
- 在没有上下文参数的情况下调用本机绑定函数(function.prototype.bind)
- 为什么Function.prototype.bind很慢?
- 在EventListeners上使用function.prototype.bind()
- 为什么使用Function.prototype.bind而不是Function.prototype.call ?
- Function.prototype.bind
- Javascript Function.prototype.bind的变化我想确保我理解
- 在回调中可以替代function.prototype.bind