每个人似乎都普遍认为原型继承比类继承更简单、更灵活。我在我读过的文献中没有看到很多例子,你可以用原型继承来做你不能用经典继承来做的事情。所以我提出一个简单的问题:
有哪些模式可以用于原型继承,而不能用于类继承,以及何时/如果使用它,你会给出什么指导?
每个人似乎都普遍认为原型继承比类继承更简单、更灵活。我在我读过的文献中没有看到很多例子,你可以用原型继承来做你不能用经典继承来做的事情。所以我提出一个简单的问题:
有哪些模式可以用于原型继承,而不能用于类继承,以及何时/如果使用它,你会给出什么指导?
一个区别(也许至少在概念上)是类继承意味着子类是父类的 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"
如果您的对象突然需要以完全不同但一致的方式开始响应某种全局事件,这将很有用。也许是这样的:
由于 JavaScript 中没有真正的类继承,你可能永远找不到任何文献解释 JavaScript 中经典类继承不能做什么,除非你将它与其他语言中的类继承进行比较。
所以我会考虑你的问题,就好像你的意思是:
有哪些模式可以用于 JavaScript 原型继承,而在支持它的语言中不能用于类继承?
R= 一般来说,大多数基于类继承的面向对象语言产生具有刚性结构的对象,它们在其生命周期中总是具有相同的方法和属性,并且相同类的所有对象将具有相同的结构。
因此,一般而言,您可以使用无法使用类继承语言实现的基于原型的语言应用的模式取决于:
*这在 JavaScript 中得到了很好的支持,因为它是动态的跨域协作性质。有时您需要从其他网站加载外部脚本,但需要添加新功能而无法更改这些外部库的源代码。
我认为我不同意您的前提,但基于原型的继承的主要好处是它允许对类的所有成员进行属性和方法的运行时分配,即使已经存在该类的实例。
我内心的理论家实际上对其中的一些含义感到畏缩。想象一下调试一些你不知道哪段代码完全重新定义了你的类结构的东西。这是令人生畏的。
但是,我会说,它已被证明是有用的:
有一次,当我在 ActionScript 3 容器内使用 ActionScript 2(不适合胆小的人,因为它几乎是一种非确定性语言)时。这个问题的一个未知副作用是它消除了内存级别的想法(这对我公司的遗留代码至关重要)。我能够添加该行:MovieClip.prototype._level0 = _root;
它解决了问题。
为了反驳我的上述论点,在您无法访问原始代码库(如示例)的情况下,您可以在事后修改所有实例这一事实确实为您提供了一定的权力,但我认为没有重大意义受益不止于此。