我可以从JavaScript中的绑定函数获取未绑定的函数吗?

时间:2012-05-09 19:47:27

标签: javascript function bind ecmascript-5

我正在使用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

是否可以从绑定函数中检索原始的未绑定函数?

3 个答案:

答案 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设置了上下文,就无法更改上下文。

Chained bind calls

答案 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似乎都得到相同的结果,有时正常版本更快,而有时被覆盖更快。