为什么Function.bind(“foo”)。call(“bar”)总是将此引用为“foo”?

时间:2011-08-27 10:05:27

标签: javascript ecmascript-5

我刚刚在JS中遇到了一个我无法理解的行为:我想创建一个调用String.prototype.replace并给出一些args的方法,因此我提出了这个:

String.prototype.replace.bind("foo", /bar/g, function(){}).call

我猜我会得到一个函数,我只需要输入一个字符串来获取我的替换。相反,我总是得到最初的this - 值(在这种情况下为foo)。

现在我的问题是:

  • 为什么JS表现得那样? bind真正返回的是什么,如何获得this的{​​{1}} - 参数?
  • 在没有创建包装函数的情况下,还有另一种方法可以做我想做的事吗?

3 个答案:

答案 0 :(得分:2)

Function.bind返回一个新函数,当被调用时,它将始终使用绑定上下文调用原始函数。

可以像这样实现Function.bind:

Function.prototype.bind = function(context) {
    var origFunction = this;
    return function() {
        return origFunction.apply(context, arguments);
    };
};

您可以在此处尝试:http://jsfiddle.net/HeRU6/

因此,当您执行somefunction.bind("foo")时,它会返回一个新函数。调用此新功能将始终以somefunction作为上下文调用"foo"

您可以编写一个只绑定参数的函数,而不是上下文:

Function.prototype.curry = function() {
    var origFunction = this, args = Array.prototype.slice.call(arguments);
    return function() {
        console.log(args, arguments);
        return origFunction.apply(this, Array.prototype.concat.apply(args, arguments));
    };
};

a = function() { console.log(this, arguments); };

b = a.curry(1, 2);
b(); // Window [1, 2]
b(3); // Window [1, 2, 3]
b.call("foo", 4); // "foo" [1, 2, 4]

答案 1 :(得分:2)

为什么会这样?

您将this的{​​{1}}值传递给call返回的函数。但是,bind忽略该值并使用绑定的bind调用原始函数(例如this)。事实上,foo 意味着绑定bind值。你可以绑定的this是另外的东西。

解决它

如果没有包装功能,我认为你不能做你想做的事。但是,使用包装函数,您可以执行以下操作:

arguments

E.g。

Function.prototype.bindArgs = function() {
    var args = arguments,
        func = this;

    return function(context) {
        return func.apply(context, args);
    }
};

答案 2 :(得分:1)

  

为什么JS表现得那样?

因为这是standard中定义的方式。

  

bind真正返回什么,如何获得.call()的this参数?

g = f.bind(foo, bar, ...)function g() { return f.call(foo, bar, ...); }完全相同 由于this中没有g,您无法从通话中恢复。

  

有没有另一种方法可以在不创建包装函数的情况下做我想做的事情?

可能不是。