避免使用.call()和.apply(),改为使用.bind()

15

我正在寻找一种方法来完成特定任务,即从

jQuery.when.apply( null, promiseArray ).done(...)

when( promiseArray ).done(...)

你可能知道,.bind() 可以用于创建类似默认参数的东西,也可以做一些非常聪明的事情。例如,不是总是调用

var toStr = Object.prototype.toString;
// ...
toStr.call([]) // [object Array]

我们可以这样做

var toStr = Function.prototype.call.bind( Object.prototype.toString );
toStr([]) // [object Array]

这很酷(尽管像这样调用.bind()会有一定的性能损失,我知道它,也意识到了它),但我无法真正实现它来处理jQuery的.when方法调用。如果你有未知数量的promise对象,通常会将它们推入一个数组中,然后像我上面的第一个代码片段那样传递给.when方法。

到目前为止,我的做法是:

var when = Function.prototype.apply.bind( $.when );

现在我们可以像这样进行

when( null, promiseArray ).done(...)

这个代码可以运行,但我也想摆脱每次都需要显式传递 null 的需求。因此我尝试了以下方法:

var when = Function.prototype.apply.bind( $.when.call.bind( null ) );

但是它会抛出一个异常:

"TypeError: Function.prototype.apply called on incompatible null"

我想我已经坐在这个问题上太久了,现在无法清晰地思考。感觉有一个简单的解决方案。我不想使用任何其他的函数来解决这个问题,我希望使用.bind()来实现。

在这里可以看到完整的示例:http://jsfiddle.net/pp26L/


@Raynos:耶,把盐擦到我的受伤自尊心上.. :p - jAndy
2个回答

10

这应该可以正常工作:

when = Function.prototype.apply.bind( $.when, null);

您只需要绑定(或者柯里化,如果您更喜欢这个说法).bind 的第一个参数并将其固定为 null

演示.


哎呀,我肯定在某个时候做过那个。我怎么会错过它呢?至少我知道这是一个相对简单的解决方案,用于一个大问题。谢谢@Jon! - jAndy
@jAndy:考虑到你的JS技能比我好得多,很明显是因为疲劳而错过了它。干杯。 - Jon

7

bind 接收可变数量的参数,因此您可以部分应用方法。所以,不是:

var when = Function.prototype.apply.bind( $.when );

请这样做:

var when = Function.prototype.apply.bind( $.when , null );

这是更新过的 jsfiddle:http://jsfiddle.net/pp26L/2/


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接