在Function.prototype中得到“ TypeError:无法将未定义或null转换为对象”

时间:2019-11-12 09:33:13

标签: javascript this prototype

出于学习目的,我编写了一段(无意义的)代码,如下所示:

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方法中的invokepush,但是this的{​​{1}}(this的呼叫者)是push,这不是一个类似数组的对象(?)。但是为什么错误是window

究竟该错误的原因是什么?有什么办法可以纠正吗?

1 个答案:

答案 0 :(得分:1)

Array.prototype.pushArray.prototype.push的功能相同,并且arr.push(1, 2); 需要一个 calling上下文来标识要推送参数的数组至。与

.

调用上下文(在调用函数时在arr之前)是invoke。但是,您的return this(...args); 没有调用上下文:

call

出于相同的原因,您无法在pushundefined 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 invokeFunction.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}}