出于学习目的,我编写了一段(无意义的)代码,如下所示:
Function.prototype.invoke = function(...args) {
return this(...args);
}
const foo = (a, b) => a + b;
console.log(foo.invoke(1, 2)); // 3, all right!
const arr = [];
arr.push.invoke(1,2); // TypeError: Cannot convert undefined or null to object
console.log(arr);
这里,我在Function
的原型invoke
上定义了一个方法,该方法仅用于通过foo.invoke(args)
调用函数(而不是传统的方法foo(args)
) 。我想知道为什么foo
无法运行,而arr.push
却不能运行。
据我所知,这是由this
问题引起的。我的this
方法中的invoke
是push
,但是this
的{{1}}(this
的呼叫者)是push
,这不是一个类似数组的对象(?)。但是为什么错误是window
?
究竟该错误的原因是什么?有什么办法可以纠正吗?
答案 0 :(得分:1)
Array.prototype.push
与Array.prototype.push
的功能相同,并且arr.push(1, 2);
需要一个 calling上下文来标识要推送参数的数组至。与
.
调用上下文(在调用函数时在arr
之前)是invoke
。但是,您的return this(...args);
没有调用上下文:
call
出于相同的原因,您无法在push
上undefined
Array.prototype.push.call(undefined, 1, 2);
:
this
如果您要“调用”需要调用上下文的函数,则可以将.call
值作为第一个参数并使用Function.prototype.invoke = function(thisVal, ...args) {
return this.apply(thisVal, args);
}
const foo = (a, b) => a + b;
console.log(foo.invoke(undefined, 1, 2)); // 3, all right!
const arr = [];
arr.push.invoke(arr, 1,2);
console.log(arr);
:
bind
您也可以在致电arr.push
之前将arr
invoke
到Function.prototype.invoke = function(...args) {
return this(...args);
}
const foo = (a, b) => a + b;
console.log(foo.invoke(1, 2)); // 3, all right!
const arr = [];
arr.push.bind(arr).invoke(1,2);
console.log(arr);
:
{{1}}