我正在使用Function.prototype.bind
将头脑缠绕在currying和其他技巧上
在某些情况下改变函数范围(即this
值)似乎非常有用。
然而it looks like you can't change the scope with bind
一旦你已经这样做了:
function f = obj.method.bind(42);
function g = obj.method.bind('Hi');
function f2 = f.bind('Hi'); // “this” is still 42
是否可以从绑定函数中检索原始的未绑定函数?
答案 0 :(得分:26)
bind
方法基本上做的是(不完全是,因为参数被切片以排除上下文):
function bind(context) {
var self = this;
return function() {
self.apply(context, arguments);
}
}
所以基本上它返回另一个函数,它将使用给定的上下文和参数调用自身。如果您再次bind
,那么您将绑定这个新创建的函数,就好像bind
的实现一样:
function bind(context) {
var self = this;
return function() {
self.apply(context, arguments);
}.bind(otherContext);
}
但是因为bind返回的内部函数充当了一个闭包,其中原始上下文是第一个绑定的(self
),那个将成为你的函数的上下文将被真正执行。
答案 1 :(得分:25)
我认为用图片说明Win32's answer会很有用。
由bind
生成的包装器确保使用给定的上下文调用您的函数,无论。
这样的包装器总是会忽略它自己的上下文。
给定一系列包装,任何上下文,但最内层都会丢失
因此,一旦使用bind
设置了上下文,就无法更改上下文。
答案 2 :(得分:-1)
这实际上可以解决您的问题
const bind = Function.prototype.bind;
Object.defineProperty(Function.prototype, 'bind', {
value: function () {
const result = bind.apply(this, arguments);
result.source = this;
return result;
}
});
现在,您可以获取source
属性以获取原始功能。
这可能会导致其他问题,但是性能似乎不是其中之一,https://jsperf.com/bind-override/1
IE,Edge,Firefox和Chrome似乎都得到相同的结果,有时正常版本更快,而有时被覆盖更快。