哪些模式可以用于原型继承,而不能用于类

What are patterns you could use with prototype inheritance that you cannot with class?

本文关键字:用于 不能 继承 原型 模式      更新时间:2023-09-26

每个人似乎都普遍认为原型继承比类继承更简单、更灵活。在我读过的文献中,我没有看到很多关于原型继承的例子,而经典继承则无法做到。所以我提出一个简单的问题:

您可以在原型继承中使用哪些模式,而在类继承中则不能使用这些模式?在何时/是否使用它时,您会给出什么指导?

一个区别(也许至少在概念上)是类继承意味着父级的子is-A类型。原型继承没有这样的含义;哺乳动物是猫的原型(Merriam-Webster的定义说这意味着它是一种"模式"),但没有其他东西。猫可以自由地移除/添加/更改它认为合适的行为。

好的,我将添加一个,使用原型链接是一整类对象的猴子补丁方法的事实:

var Cat = function(catName) {
    this.catName = catName;
};
Cat.prototype.meow = function() {
    console.log(this.catName+" says meow");
}
var mittens = new Cat("Mittens");
var whiskers = new Cat("Whiskers");
mittens.meow(); // "Mittens says meow"
whiskers.meow(); // "Whiskers says meow"
// All cats are now angry
Cat.prototype.meow = function() {
    console.log(this.catName+" says hissssss");
}
mittens.meow(); // "Mittens says hissssss"
whiskers.meow(); // "Whiskers says hissssss"

如果您的对象突然需要以完全不同但一致的方式开始响应某种全局事件,那么这将非常有用。也许是像这样的东西

  • 主题和蒙皮
  • 页面是在"在线模式"还是"离线模式"下运行(在线时,所有查询都通过ajax存储/检索,而离线查询重定向到浏览器存储)

我不同意你的前提,但基于原型的继承的主要好处是,它允许在运行时为类的所有成员分配属性和方法,即使该类已经有实例。

我内心的理论家实际上对其中的一些暗示感到畏缩。想象一下,在调试某个东西时,您不知道哪段代码已经完全重新定义了您的类结构。这令人望而生畏。

但是,我要说的是,它已经被证明是有用的:

有一次,当我在ActionScript3容器中使用ActionScript2(不适合胆小的人,因为它几乎是一种不确定的语言)时。这个问题的一个未知副作用是,它消除了内存级别的概念(这对我公司的遗留代码至关重要)。我能够添加行:MovieClip.prototype._level0 = _root;,它解决了问题。

为了反驳我的上述论点,在您无法访问原始代码库(如示例)的情况下,您可以在事后修改所有实例,这一事实确实为您提供了一定的权力,但除此之外,我看不到任何重大好处。

由于JavaScript中没有真正的类继承,除非将其与其他语言中的类继承进行比较,否则您可能永远找不到任何文献来解释JavaScript中经典类继承所不能做的事情。

所以我会考虑你的问题,就好像你的意思是:

在支持JavaScript原型继承的语言中,有哪些模式可以用于JavaScript原型继承,而不能用于类继承?

R=通常,大多数基于类继承的面向对象语言都会生成具有刚性结构的对象,它们在使用寿命内始终具有相同的方法和属性,并且相同类的所有对象都具有相同的结构。

所以,一般来说,你可以用基于原型的语言应用的模式,而不能用类继承语言实现,这些模式依赖于:

  • 动态向对象添加或删除方法或属性

*这在JavaScript中得到了很好的支持,因为它是动态的,具有跨域协作的特性。有时,您需要从其他网站加载外部脚本,但需要添加新功能,而无法更改这些外部库中的源代码。

相关文章: