gpt4 book ai didi

javascript - 像普通子方法一样通过子对象访问父原型(prototype)方法

转载 作者:行者123 更新时间:2023-12-05 01:50:30 25 4
gpt4 key购买 nike

看来我又一次没有正确理解原型(prototype)。

如果您在一个对象上调用一个方法,但它不存在 - 它不会检查该方法可以运行它的原型(prototype)吗?

喜欢

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

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

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

另外:我仅限于 ES5 代码

基本模块设置

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();

一起使用

最佳答案

If you call a method on an object, and it doesn't exist - does it not check the prototype for the method can run it?

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

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

这不会使 Wall.prototype 成为 OtherWall.prototype 的原型(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 绑定(bind)到实例,则需要在构造函数中执行此操作。

2。我建议使方法不可枚举,就像 ES2015 的 class 语法一样,并且像 JavaScript 始终具有的 constructor 属性一样。当您通过简单赋值创建属性时,该属性是可枚举的。

3。我认为您在 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 - 像普通子方法一样通过子对象访问父原型(prototype)方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73018918/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com