JavaScript: call vs call.bind



为什么在下面的代码中,第 3 行有效,而第 4 行不起作用?

function out(x) {
  console.log(x);
}
out.call(window, "bla") // outputs "bla"
out.call.bind(window, "bla")(); // throws "TypeError: object is not a function"

问题是你可能有一个错别字:你打算写out.bind(window, "bla")(),这将产生与有效的调用相同的结果。

为什么当前代码出错?Well out.call.bind 返回一个函数,该函数将 this 的值固定在 callwindow 内。但是,call希望this是一个函数,而window不是。结果是给定的错误。

从带注释的 ES5 规范中:

15.3.4.5 Function.prototype.bind (thisArg [, arg1 [, arg2, ...]])

绑定方法采用一个或多个参数,thisArg 和(可选) arg1、arg2 等,并通过执行 以下步骤:

1. Let Target be the this value.
2. If IsCallable(Target) is false, throw a TypeError exception.
[...]

您正在按预期获得TypeError

补遗

out.call.bind的用法,很像类似的out.call.call,导致out.call的"重定向目标"——也就是说,它不是在out上被调用call,而是在其他东西上被调用。举个例子:

function foo(x) { console.log("this", this, "foo", x); }
function bar(x) { console.log("this", this, "bar", x); }
foo.call.bind(bar, window, 42)();  // "this" [window] "bar" 42

最新更新