像普通子方法一样通过子对象访问父原型方法

Dal*_*ods 3 javascript

看来我又没有正确理解原型了。

如果您在对象上调用方法,并且该方法不存在 - 它是否不检查该方法的原型是否可以运行它?

喜欢

Array.prototype.myArrayMagic = function () { ... }
Run Code Online (Sandbox Code Playgroud)

然后在任何数组上您都可以调用 arr.myArrayMagic() 吗?

这是我的理解,但我现在遇到了问题,除非我通过 .prototype 显式调用它,否则调用原型方法将不起作用

另外:我仅限于 ES5 代码

基本模块设置

function Wall() {}

Wall.prototype = {

    shouldShowWall: function() {
        return true;
    },

    show: function () {
        if (!this.shouldShowWall()) {
            return;
        }

        // Do other stuff here
    }
}

module.exports = Wall;
Run Code Online (Sandbox Code Playgroud)

子对象

function OtherWall() {
    this.item = 'my_tracking_id',
    this.minutes = 30
    // ...
}

OtherWall.prototype = {
    constructor: Object.create(Wall.prototype),

    /**
     * Override wall.prototype.shouldShowWall method for deciding if the wall should be shown at this time
     */
    shouldShowWall: function() {
        // return true or flase here
    }.bind(this)
}

module.exports = OtherWall;
Run Code Online (Sandbox Code Playgroud)

因此,遵循其他答案并尝试尽可能最好地理解,这应该以我可以调用的方式设置

new OtherWall().show();
Run Code Online (Sandbox Code Playgroud)

但这不起作用,只有当我打电话时它才起作用

new OtherWall().prototype.show();
Run Code Online (Sandbox Code Playgroud)

这是正常现象还是我设置错了?

我需要改变什么才能让它工作OtherWall().show();

T.J*_*der 5

如果您在对象上调用方法,并且该方法不存在 - 它是否不检查该方法的原型是否可以运行它?

是的,它确实如此(就像任何属性一样),但此代码不正确:

OtherWall.prototype = {
    constructor: Object.create(Wall.prototype)
    // ...
Run Code Online (Sandbox Code Playgroud)

那不会形成Wall.prototype的原型OtherWall.prototype。为此,请执行以下操作:

OtherWall.prototype = Object.create(Wall.prototype);
Run Code Online (Sandbox Code Playgroud)

然后在 上添加属性OtherWall.prototype,从 开始 constructor

// But keep reading, I wouldn't do it quite like this
OtherWall.prototype.constructor = OtherWall;
Run Code Online (Sandbox Code Playgroud)

...然后shouldShowWall等等

我在这里的回答可能也有用,它显示了使用 ES5 语法创建一个“子类”(与 ES2015 的class语法对比)。

另外一些注意事项:

1. 这看起来可能不是你想要的:

/**
 * Override wall.prototype.shouldShowWall method for deciding if the wall should be shown at this time
 */
shouldShowWall: function() {
    // return true or flase here
}.bind(this)
Run Code Online (Sandbox Code Playgroud)

this在范围内没有 的实例,OtherWall它是this该对象字面量之外的任何内容。如果您想绑定shouldShowWall到实例,则需要在构造函数中执行此操作。

2. 我建议将方法设置为不可枚举,就像 ES2015 的class语法一样,对于 constructor JavaScript 的属性也同样如此。当您通过简单赋值创建属性时,该属性是可枚举的。

3. 我认为你有一个拼写错误OtherWall,你,在第一个语句的末尾使用了 a 而不是 a ;。从技术上讲,由于逗号运算符,它是有效的,但我不认为您是故意使用逗号运算符的。:-)

这是应用上述所有内容的示例;Object.defineProperty是一个 ES5 方法(我不太习惯编写 ES5 代码,但我想我已经在这里避免了所有 ES2015+ 的东西):

OtherWall.prototype = {
    constructor: Object.create(Wall.prototype)
    // ...
Run Code Online (Sandbox Code Playgroud)