我正在使用Function.prototype.bind
. 在某些情况下更改函数范围(即值)
似乎非常有用。this
但是,一旦您这样做了,您似乎就无法更改范围:bind
function f = obj.method.bind(42);
function g = obj.method.bind('Hi');
function f2 = f.bind('Hi'); // “this” is still 42
是否可以从绑定函数中检索原始未绑定函数?
我正在使用Function.prototype.bind
. 在某些情况下更改函数范围(即值)
似乎非常有用。this
但是,一旦您这样做了,您似乎就无法更改范围:bind
function f = obj.method.bind(42);
function g = obj.method.bind('Hi');
function f2 = f.bind('Hi'); // “this” is still 42
是否可以从绑定函数中检索原始未绑定函数?
该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
),因此将真正执行函数中的上下文。
我认为用图片来说明Win32 的答案会很有用。
由 生成的包装器bind
确保您的函数在给定的上下文中被调用,无论如何。
这样的包装器总是会忽略它自己的上下文。
给定一个包装链,除了最里面的任何上下文都会丢失。
因此,一旦使用bind
.
这实际上会解决你的问题
const bind = Function.prototype.bind;
Object.defineProperty(Function.prototype, 'bind', {
value: function () {
const result = bind.apply(this, arguments);
result.source = (this.source || this);
return result;
}
});
现在你可以获取source
属性来获取原始函数。这可能会导致其他问题,但性能似乎不是其中之一,https://jsperf.com/bind-override/1
IE、Edge、Firefox 和 Chrome 似乎都得到了相同的结果,有时普通版本更快,有时覆盖更快。