为什么在下面的代码中,第 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
的值固定在 call
到 window
内。但是,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