从功能继承时呼叫的意外行为



我正在尝试编写一个将从函数继承的类,但是我无法在类的实例上打电话。

例如,假设我定义了构造函数:

function myFunc() {
    Function.call(this);}

我将 myFunc 的原型设置为函数:

myFunc.prototype = Function.prototype

我创建一个新类的实例:

var f = new myFunc()

我可以看到f.__proto__Function.prototype

f.__proto__ === Function.prototype /=> true

Function.prototype具有呼叫方法:

 Function.prototype.call /=> ƒ call() { [native code] }

nonetheless f.call(null)返回错误:

f.call(null) /=> VM183:1 Uncaught TypeError: f.call is not a function
at <anonymous>:1:3

这里发生了什么?

我认为f.call会检查f.__proto__是否有呼叫方法,但这似乎并没有发生。

一个人不仅仅是扩展内置类,至少不是历史上的。

正确扩展内置类的能力是ES6功能,该功能通常依赖于使用ES6语法。

class MyClass extends SomeBuiltin {}

es5语法在这里并不真正起作用,它会导致无法正确实现内部内容的对象,并最终失败了方法,因此需要它(给您看似错误的呼叫方法错误)。

如果您的JavaScript环境支持扩展功能,这将有效:

class myFunc extends Function {
    constructor() {
        super('return [...arguments]');
    }
}
const f = new myFunc();
console.log(f.call(null, 1, 2, 3)); // [1, 2, 3]

我倾向于首先建议不要延长Function,因为它需要从字符串中进行代码评估,这是不愉快的,潜在的危险且通常不必要的。

最新更新