似乎我又一次没有正确理解原型.

如果你在一个对象上调用了一个方法,但它不存在——它不判断该方法是否可以运行它的原型吗?

喜欢

Array.prototype.myArrayMagic = function () { ... }

那么在任何数组上都可以调用arr.myArrayMagic()?

这是我的理解,但我现在遇到了一个问题,即除非我显式地调用原型方法,否则调用原型方法将无法工作.原型

Also: I am restricted to ES5 code

基本模块设置

function Wall() {}

Wall.prototype = {

    shouldShowWall: function() {
        return true;
    },

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

        // Do other stuff here
    }
}

module.exports = Wall;

子对象

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;

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

new OtherWall().show();

但它不起作用,只有我打电话才能起作用

new OtherWall().prototype.show();

这正常吗,还是我设置错了?

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

推荐答案

如果你在一个对象上调用了一个方法,但它不存在——它不判断该方法是否可以运行它的原型吗?

是的,它确实存在(与任何属性一样),但此代码不正确:

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

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

OtherWall.prototype = Object.create(Wall.prototype);

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

// But keep reading, I wouldn't do it quite like this
OtherWall.prototype.constructor = OtherWall;

...然后是shouldShowWall,等等.

我的答案here也可能有用,它显示了使用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)

作用域中的this不是OtherWall的实例,而是在该对象文字外的任何this.如果要将shouldShowWall绑定到实例,则需要在构造函数中执行此操作.

2.我建议让方法不可枚举,就像ES2015的class个语法一样,对于constructor个属性也一样,比如JavaScript.通过简单赋值创建属性时,该属性是可枚举的.

我认为你的OtherWall有错,你在第一句话的末尾用了,而不是;.从技术上讲,它是有效的,因为逗号运算符,但我认为您不是故意使用逗号运算符的.:-)

下面是一个应用上述所有内容的示例;Object.defineProperty是一种ES5方法(我没有练习编写ES5代码,但我认为我在这里避免了所有ES2015以上的东西):

function assignNonEnumerable(target, source) {
    Object.keys(source).forEach(function (key) {
        Object.defineProperty(target, key, {
            value: source[key],
            configurable: true,
            writable: true,
            enumerable: false, // This is the default, but showing it here for emphasis
        });
    });
}

function Wall() {
}

assignNonEnumerable(Wall.prototype, {
    shouldShowWall: function () {
        return true;
    },

    show: function () {
        console.log("show called");
        if (!this.shouldShowWall()) {
            return;
        }

        // Do other stuff here
    },
});

function OtherWall() {
    this.item = "my_tracking_id";
    this.minutes = 30;
    // If you want to bind it to the instance:
    this.shouldShowWall = this.shouldShowWall.bind(this);
}

OtherWall.prototype = Object.create(Wall.prototype);
assignNonEnumerable(OtherWall.prototype, {
    constructor: OtherWall,
    shouldShowWall: function () {
        // You can't bind the instance here, see the constructor above
        console.log("shouldShowWall called");
        return Math.random() < 0.5;
    },
});

new OtherWall().show();

Javascript相关问答推荐

promise .all()永不解决

在JS中转换mysql UTC时间字段?

Express.js:以块形式发送响应

React redux状态未在React-Router库中呈现

一次仅播放一个音频

微软Edge Select 间隙鼠标退出问题

google docs boldText直到按行执行应用脚本错误

我怎么才能得到Kotlin的密文?

如何控制Reaction路由加载器中的错误状态?

如果Arrow函数返回函数,而不是为useEffect返回NULL,则会出现错误

用于在路径之间移动图像的查询

基于props 类型的不同props ,根据来自接口的值扩展类型

如何在不影响隐式类型的情况下将类型分配给对象?

Vaadin定制组件-保持对javascrip变量的访问

使用插件构建包含chart.js提供程序的Angular 库?

当代码另有说明时,随机放置的圆圈有时会从画布上消失

无法读取未定义的属性(正在读取合并)-react RTK

在表单集中保存更改时删除';禁用';

在D3条形图中对具有相同X值的多条记录进行分组

如何在Java脚本中并行运行for或任意循环的每次迭代