4

我刚刚在 JS 中经历了一个我无法理解的行为:我想创建一个调用 String.prototype.replace 并给出一些参数的方法,因此我想出了:

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

我猜我会得到一个函数,我只需要输入一个字符串就可以得到我的替换。相反,我总是得到返回的初始this值(在这种情况下foo)。

现在我的问题是:

  • 为什么 JS 会这样?bind 真正返回的是什么,我怎样才能得到this-parameter .call()
  • 有没有另一种方法可以在不创建包装函数的情况下做我想做的事情?
4

3 回答 3

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]
于 2011-08-27T10:10:02.933 回答
2

为什么会这样

您将一些this值传递call给由bind. bind但是,忽略该值并使用边界调用原始函数this(例如foo)。其实bind就是为了绑定this值。arguments你可以绑定的是额外的东西。

解决它

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

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

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

例如

var func = function(a, b, c) {
    console.log(this, a, b, c);
};

var bound = func.bindArgs(1, 2, 3);
bound([1]); // [1] 1 2 3
bound({a: 1}); // {a: 1} 1 2 3
于 2011-08-27T10:14:04.090 回答
1

为什么 JS 会这样?

因为这是标准中定义的方式。

bind 真正返回的是什么,我怎样才能得到 .call() 的 this 参数?

g = f.bind(foo, bar, ...)function g() { return f.call(foo, bar, ...); } 与由于没有thisin完全相同g,因此您无法从调用中取回它。

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

可能不是。

于 2011-08-27T10:16:39.963 回答