Javascript 原型继承相对于经典继承的好处?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2800964/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Benefits of prototypal inheritance over classical?
提问by Pierreten
So I finally stopped dragging my feet all these years and decided to learn JavaScript "properly". One of the most head-scratching elements of the languages design is it's implementation of inheritance. Having experience in Ruby, I was really happy to see closures and dynamic typing; but for the life of me can't figure out what benefits are to be had from object instances using other instances for inheritance.
所以这些年来我终于停止了拖延,并决定“正确地”学习 JavaScript。语言设计中最令人头疼的元素之一是继承的实现。有 Ruby 经验,我很高兴看到闭包和动态类型;但是对于我的一生,我无法弄清楚使用其他实例进行继承的对象实例有什么好处。
回答by Aadit M Shah
I know that this answer is 3 years late but I really think the current answers do not provide enough information about how prototypal inheritance is better than classical inheritance.
我知道这个答案晚了 3 年,但我真的认为当前的答案没有提供足够的信息,说明原型继承比经典继承更好。
First let's see the most common arguments JavaScript programmers state in defence of prototypal inheritance (I'm taking these arguments from the current pool of answers):
首先让我们看看 JavaScript 程序员为保护原型继承而陈述的最常见的论点(我从当前的答案池中获取这些论点):
- It's simple.
- It's powerful.
- It leads to smaller, less redundant code.
- It's dynamic and hence it's better for dynamic languages.
- 这很简单。
- 它很强大。
- 它导致更小、更少冗余的代码。
- 它是动态的,因此更适合动态语言。
Now these arguments are all valid, but nobody has bothered explaining why. It's like telling a child that studying Maths is important. Sure it is, but the child certainly doesn't care; and you can't make a child like Maths by saying that it's important.
现在这些论点都是有效的,但没有人费心解释原因。这就像告诉孩子学习数学很重要。当然是,但孩子肯定不在乎;你不能说数学很重要就让孩子喜欢数学。
I think the problem with prototypal inheritance is that it's explained from the perspective of JavaScript. I love JavaScript, but prototypal inheritance in JavaScript is wrong. Unlike classical inheritance there are two patterns of prototypal inheritance:
我认为原型继承的问题在于它是从 JavaScript 的角度来解释的。我喜欢 JavaScript,但 JavaScript 中的原型继承是错误的。与经典继承不同,原型继承有两种模式:
- The prototypal pattern of prototypal inheritance.
- The constructor pattern of prototypal inheritance.
- 原型继承的原型模式。
- 原型继承的构造函数模式。
Unfortunately JavaScript uses the constructor pattern of prototypal inheritance. This is because when JavaScript was created, Brendan Eich(the creator of JS) wanted it to look like Java (which has classical inheritance):
不幸的是,JavaScript 使用原型继承的构造函数模式。这是因为在创建 JavaScript 时,Brendan Eich(JS 的创建者)希望它看起来像 Java(具有经典继承):
And we were pushing it as a little brother to Java, as a complementary language like Visual Basic was to C++ in Microsoft's language families at the time.
我们将它作为 Java 的小兄弟来推动,就像 Visual Basic 在当时微软的语言家族中对 C++ 的补充一样。
This is bad because when people use constructors in JavaScript they think of constructors inheriting from other constructors. This is wrong. In prototypal inheritance objects inherit from other objects. Constructors never come into the picture. This is what confuses most people.
这很糟糕,因为当人们在 JavaScript 中使用构造函数时,他们认为构造函数是从其他构造函数继承的。这是错误的。在原型继承中,对象从其他对象继承。构造函数永远不会出现。这是大多数人困惑的地方。
People from languages like Java, which has classical inheritance, get even more confused because although constructors look like classes they don't behave like classes. As Douglas Crockfordstated:
来自 Java 等具有经典继承的语言的人更加困惑,因为尽管构造函数看起来像类,但它们的行为却不像类。正如道格拉斯·克罗克福德所说:
This indirection was intended to make the language seem more familiar to classically trained programmers, but failed to do that, as we can see from the very low opinion Java programmers have of JavaScript. JavaScript's constructor pattern did not appeal to the classical crowd. It also obscured JavaScript's true prototypal nature. As a result, there are very few programmers who know how to use the language effectively.
这种间接性的目的是让受过经典训练的程序员看起来更熟悉该语言,但未能做到这一点,正如我们从 Java 程序员对 JavaScript 的非常低的看法中可以看出的那样。JavaScript 的构造函数模式对经典人群没有吸引力。它还掩盖了 JavaScript 真正的原型性质。因此,很少有程序员知道如何有效地使用该语言。
There you have it. Straight from the horse's mouth.
你有它。直接从马嘴里说出来。
True Prototypal Inheritance
真正的原型继承
Prototypal inheritance is all about objects. Objects inherit properties from other objects. That's all there is to it. There are two ways of creating objects using prototypal inheritance:
原型继承是关于对象的。对象从其他对象继承属性。这里的所有都是它的。有两种使用原型继承创建对象的方法:
- Create a brand new object.
- Clone an existing object and extend it.
- 创建一个全新的对象。
- 克隆现有对象并扩展它。
Note:JavaScript offers two ways to clone an object - delegationand concatenation. Henceforth I'll use the word "clone" to exclusively refer to inheritance via delegation, and the word "copy" to exclusively refer to inheritance via concatenation.
注意:JavaScript 提供了两种方法来克隆对象 -委托和串联。从今以后,我将使用“克隆”一词专指通过委托进行的继承,而将“复制”一词专指通过串联进行的继承。
Enough talk. Let's see some examples. Say I have a circle of radius 5:
够了。让我们看一些例子。假设我有一个半径圆5:
var circle = {
radius: 5
};
We can calculate the area and the circumference of the circle from its radius:
我们可以从半径计算圆的面积和周长:
circle.area = function () {
var radius = this.radius;
return Math.PI * radius * radius;
};
circle.circumference = function () {
return 2 * Math.PI * this.radius;
};
Now I want to create another circle of radius 10. One way to do this would be:
现在我想创建另一个半径圆10。一种方法是:
var circle2 = {
radius: 10,
area: circle.area,
circumference: circle.circumference
};
However JavaScript provides a better way - delegation. The Object.createfunction is used to do this:
然而 JavaScript 提供了一种更好的方式——委托。该Object.create函数用于执行此操作:
var circle2 = Object.create(circle);
circle2.radius = 10;
That's all. You just did prototypal inheritance in JavaScript. Wasn't that simple? You take an object, clone it, change whatever you need to, and hey presto - you got yourself a brand new object.
就这样。您刚刚在 JavaScript 中进行了原型继承。是不是很简单?你拿一个物体,克隆它,改变你需要的任何东西,嘿,很快——你得到了一个全新的物体。
Now you might ask, "How is this simple? Every time I want to create a new circle I need to clone circleand manually assign it a radius". Well the solution is to use a function to do the heavy lifting for you:
现在您可能会问,“这怎么简单?每次我想创建一个新圆时,我都需要克隆circle并手动为其分配一个半径”。那么解决方案是使用一个函数来为你做繁重的工作:
function createCircle(radius) {
var newCircle = Object.create(circle);
newCircle.radius = radius;
return newCircle;
}
var circle2 = createCircle(10);
In fact you can combine all of this into a single object literal as follows:
事实上,您可以将所有这些组合成一个单一的对象字面量,如下所示:
var circle = {
radius: 5,
create: function (radius) {
var circle = Object.create(this);
circle.radius = radius;
return circle;
},
area: function () {
var radius = this.radius;
return Math.PI * radius * radius;
},
circumference: function () {
return 2 * Math.PI * this.radius;
}
};
var circle2 = circle.create(10);
Prototypal Inheritance in JavaScript
JavaScript 中的原型继承
If you notice in the above program the createfunction creates a clone of circle, assigns a new radiusto it and then returns it. This is exactly what a constructor does in JavaScript:
如果您在上面的程序中注意到该create函数创建了 的克隆circle,为其分配一个新的radius,然后返回它。这正是 JavaScript 中构造函数的作用:
function Circle(radius) {
this.radius = radius;
}
Circle.prototype.area = function () {
var radius = this.radius;
return Math.PI * radius * radius;
};
Circle.prototype.circumference = function () {
return 2 * Math.PI * this.radius;
};
var circle = new Circle(5);
var circle2 = new Circle(10);
The constructor pattern in JavaScript is the prototypal pattern inverted. Instead of creating an object you create a constructor. The newkeyword binds the thispointer inside the constructor to a clone of the prototypeof the constructor.
JavaScript 中的构造器模式是原型模式的反转。你创建一个构造函数而不是创建一个对象。的new关键字结合this构造内部指针的一个克隆prototype的构造的。
Sounds confusing? It's because the constructor pattern in JavaScript unnecessarily complicates things. This is what most programmers find difficult to understand.
听起来很混乱?这是因为 JavaScript 中的构造函数模式不必要地使事情复杂化。这是大多数程序员难以理解的。
Instead of thinking of objects inheriting from other objects they think of constructors inheriting from other constructors and then become utterly confused.
他们没有考虑从其他对象继承的对象,而是考虑从其他构造函数继承的构造函数,然后变得完全混乱。
There's a whole bunch of other reasons why the constructor pattern in JavaScript should be avoided. You can read about them in my blog post here: Constructors vs Prototypes
应该避免使用 JavaScript 中的构造函数模式还有很多其他原因。你可以在我的博客文章中阅读它们:构造函数与原型
So what are the benefits of prototypal inheritance over classical inheritance? Let's go through the most common arguments again, and explain why.
那么原型继承相对于经典继承有什么好处呢?让我们再次回顾一下最常见的论点,并解释原因。
1. Prototypal Inheritance is Simple
1.原型继承很简单
CMSstates in his answer:
CMS在他的回答中指出:
In my opinion the major benefit of prototypal inheritance is its simplicity.
在我看来,原型继承的主要好处是它的简单性。
Let's consider what we just did. We created an object circlewhich had a radius of 5. Then we cloned it and gave the clone a radius of 10.
让我们考虑一下我们刚刚做了什么。我们创建了circle一个半径为的对象5。然后我们克隆了它并给了它一个半径为10.
Hence we only need two things to make prototypal inheritance work:
因此,我们只需要两件事就可以使原型继承工作:
- A way to create a new object (e.g. object literals).
- A way to extend an existing object (e.g.
Object.create).
- 一种创建新对象(例如对象文字)的方法。
- 一种扩展现有对象的方法(例如
Object.create)。
In contrast classical inheritance is much more complicated. In classical inheritance you have:
相比之下,经典继承要复杂得多。在经典继承中,您有:
- Classes.
- Object.
- Interfaces.
- Abstract Classes.
- Final Classes.
- Virtual Base Classes.
- Constructors.
- Destructors.
- 班级。
- 目的。
- 接口。
- 抽象类。
- 期末班。
- 虚拟基类。
- 构造函数。
- 破坏者。
You get the idea. The point is that prototypal inheritance is easier to understand, easier to implement, and easier to reason about.
你明白了。关键是原型继承更容易理解,更容易实现,也更容易推理。
As Steve Yegge puts it in his classical blog post "Portrait of a N00b":
正如 Steve Yegge 在他的经典博客文章“ N00b 的肖像”中所说:
Metadata is any kind of description or model of something else. The comments in your code are just a a natural-language description of the computation. What makes metadata meta-data is that it's not strictly necessary. If I have a dog with some pedigree paperwork, and I lose the paperwork, I still have a perfectly valid dog.
元数据是其他事物的任何类型的描述或模型。代码中的注释只是计算的自然语言描述。元数据元数据之所以成为元数据,是因为它并不是绝对必要的。如果我有一只带有一些血统文件的狗,而我丢失了文件,我仍然拥有一只完全有效的狗。
In the same sense classes are just meta-data. Classes aren't strictly required for inheritance. However some people (usually n00bs) find classes more comfortable to work with. It gives them a false sense of security.
同样,类只是元数据。继承并不严格要求类。然而,有些人(通常是 n00bs)发现课程更适合使用。这给了他们一种虚假的安全感。
Well, we also know that static types are just metadata. They're a specialized kind of comment targeted at two kinds of readers: programmers and compilers. Static types tell a story about the computation, presumably to help both reader groups understand the intent of the program. But the static types can be thrown away at runtime, because in the end they're just stylized comments. They're like pedigree paperwork: it might make a certain insecure personality type happier about their dog, but the dog certainly doesn't care.
好吧,我们也知道静态类型只是元数据。它们是一种专门针对两类读者的注释:程序员和编译器。静态类型讲述了一个关于计算的故事,大概是为了帮助两个读者群体理解程序的意图。但是静态类型可以在运行时丢弃,因为最终它们只是风格化的注释。它们就像血统文件:它可能会让某种缺乏安全感的性格类型对他们的狗更满意,但狗肯定不在乎。
As I stated earlier, classes give people a false sense of security. For example you get too many NullPointerExceptions in Java even when your code is perfectly legible. I find classical inheritance usually gets in the way of programming, but maybe that's just Java. Python has an amazing classical inheritance system.
正如我之前所说,课程给人们一种错误的安全感。例如NullPointerException,即使您的代码非常清晰,您在 Java 中也会得到太多的s。我发现经典继承通常会妨碍编程,但也许这只是 Java。Python 有一个惊人的经典继承系统。
2. Prototypal Inheritance is Powerful
2.原型继承是强大的
Most programmers who come from a classical background argue that classical inheritance is more powerful than prototypal inheritance because it has:
大多数具有经典背景的程序员认为经典继承比原型继承更强大,因为它具有:
- Private variables.
- Multiple inheritance.
- 私有变量。
- 多重继承。
This claim is false. We already know that JavaScript supports private variables via closures, but what about multiple inheritance? Objects in JavaScript only have one prototype.
这种说法是错误的。我们已经知道 JavaScript通过闭包支持私有变量,但是多重继承呢?JavaScript 中的对象只有一个原型。
The truth is that prototypal inheritance supports inheriting from multiple prototypes. Prototypal inheritance simply means one object inheriting from another object. There are actually two ways to implement prototypal inheritance:
事实是原型继承支持从多个原型继承。原型继承仅仅意味着一个对象从另一个对象继承。实际上有两种方法可以实现原型继承:
- Delegation or Differential Inheritance
- Cloning or Concatenative Inheritance
- 委托或差分继承
- 克隆或串联继承
Yes JavaScript only allows objects to delegate to one other object. However it allows you to copy the properties of an arbitrary number of objects. For example _.extenddoes just this.
是 JavaScript 只允许对象委托给另一个对象。但是,它允许您复制任意数量的对象的属性。例如_.extend就是这样做。
Of course many programmers don't consider this to be true inheritance because instanceofand isPrototypeOfsay otherwise. However this can be easily remedied by storing an array of prototypes on every object which inherits from a prototype via concatenation:
当然,许多程序员并不认为这是真正的继承,因为instanceof并isPrototypeOf另有说法。然而,这可以通过在通过串联从原型继承的每个对象上存储原型数组来轻松解决:
function copyOf(object, prototype) {
var prototypes = object.prototypes;
var prototypeOf = Object.isPrototypeOf;
return prototypes.indexOf(prototype) >= 0 ||
prototypes.some(prototypeOf, prototype);
}
Hence prototypal inheritance is just as powerful as classical inheritance. In fact it's much more powerful than classical inheritance because in prototypal inheritance you can hand pick which properties to copy and which properties to omit from different prototypes.
因此原型继承与经典继承一样强大。事实上,它比经典继承强大得多,因为在原型继承中,您可以手动选择要复制的属性以及要从不同原型中省略的属性。
In classical inheritance it's impossible (or at least very difficult) to choose which properties you want to inherit. They use virtual base classes and interfaces to solve the diamond problem.
在经典继承中,选择要继承的属性是不可能的(或者至少非常困难)。他们使用虚拟基类和接口来解决菱形问题。
In JavaScript however you'll most likely never hear of the diamond problem because you can control exactly which properties you wish to inherit and from which prototypes.
然而,在 JavaScript 中,您很可能永远不会听说过菱形问题,因为您可以准确地控制您希望继承哪些属性以及从哪些原型中继承。
3. Prototypal Inheritance is Less Redundant
3. 原型继承的冗余更少
This point is a little more difficult to explain because classical inheritance doesn't necessarily lead to more redundant code. In fact inheritance, whether classical or prototypal, is used to reduce the redundancy in code.
这一点有点难以解释,因为经典继承并不一定会导致更多的冗余代码。事实上,继承,无论是经典的还是原型的,都是用来减少代码冗余的。
One argument could be that most programming languages with classical inheritance are statically typed and require the user to explicitly declare types (unlike Haskell which has implicit static typing). Hence this leads to more verbose code.
一个论点可能是大多数具有经典继承的编程语言都是静态类型的,并且要求用户显式声明类型(与具有隐式静态类型的 Haskell 不同)。因此,这会导致更冗长的代码。
Java is notorious for this behavior. I distinctly remember Bob Nystrommentioning the following anecdote in his blog post about Pratt Parsers:
Java 因这种行为而臭名昭著。我清楚地记得Bob Nystrom在他关于Pratt Parsers 的博客文章中提到了以下轶事:
You gotta love Java's "please sign it in quadruplicate" level of bureaucracy here.
你一定会喜欢 Java 的“请一式四份”的官僚主义级别。
Again, I think that's only because Java sucks so much.
再说一次,我认为那只是因为 Java 太烂了。
One valid argument is that not all languages which have classical inheritance support multiple inheritance. Again Java comes to mind. Yes Java has interfaces, but that's not sufficient. Sometimes you really need multiple inheritance.
一个有效的论点是,并非所有具有经典继承的语言都支持多重继承。再次想到Java。是的,Java 有接口,但这还不够。有时你真的需要多重继承。
Since prototypal inheritance allows for multiple inheritance, code which requires multiple inheritance is less redundant if written using prototypal inheritance rather than in a language which has classical inheritance but no multiple inheritance.
由于原型继承允许多重继承,如果使用原型继承而不是使用具有经典继承但没有多重继承的语言编写需要多重继承的代码,则冗余更少。
4. Prototypal Inheritance is Dynamic
4.原型继承是动态的
One of the most important advantages of prototypal inheritance is that you can add new properties to prototypes after they are created. This allows you to add new methods to a prototype which will be automatically made available to all the objects which delegate to that prototype.
原型继承最重要的优点之一是您可以在原型创建后向原型添加新属性。这允许您向原型添加新方法,这些方法将自动提供给所有委托给该原型的对象。
This is not possible in classical inheritance because once a class is created you can't modify it at runtime. This is probably the single biggest advantage of prototypal inheritance over classical inheritance, and it should have been at the top. However I like saving the best for the end.
这在经典继承中是不可能的,因为一旦创建了一个类,你就不能在运行时修改它。这可能是原型继承相对于经典继承的最大优势,它应该是最重要的。不过我喜欢把最好的留到最后。
Conclusion
结论
Prototypal inheritance matters. It's important to educate JavaScript programmers on why to abandon the constructor pattern of prototypal inheritance in favor of the prototypal pattern of prototypal inheritance.
原型继承很重要。重要的是要教育 JavaScript 程序员为什么要放弃原型继承的构造函数模式而支持原型继承的原型模式。
We need to start teaching JavaScript correctly and that means showing new programmers how to write code using the prototypal pattern instead of the constructor pattern.
我们需要开始正确地教授 JavaScript,这意味着向新程序员展示如何使用原型模式而不是构造函数模式编写代码。
Not only will it be it easier to explain prototypal inheritance using the prototypal pattern, but it will also make better programmers.
使用原型模式不仅可以更容易地解释原型继承,而且还可以成为更好的程序员。
If you liked this answer then you should also read my blog post on "Why Prototypal Inheritance Matters". Trust me, you will not be disappointed.
如果您喜欢这个答案,那么您还应该阅读我关于“为什么原型继承很重要”的博客文章。相信我,你不会失望的。
回答by JUST MY correct OPINION
Allow me to actually answer the question inline.
请允许我在线回答问题。
Prototype inheritance has the following virtues:
原型继承具有以下优点:
- It is better suited to dynamic languages because the inheritance is as dynamic as the environment it is in. (The applicability to JavaScript should be obvious here.) This permits you to do things quickly on the fly like customizing classes without huge amounts of infrastructure code.
- It is easier to implement a prototyping object scheme than the classic class/object dichotomy schemes.
- It eliminates the need for the complex sharp edges around the object model like "metaclasses" (I never metaclass I liked... sorry!) or "eigenvalues" or the like.
- 它更适合动态语言,因为继承与它所处的环境一样动态。(对 JavaScript 的适用性在这里应该是显而易见的。)这允许您快速完成诸如自定义类之类的事情,而无需大量基础结构代码.
- 实现原型对象方案比经典的类/对象二分方案更容易。
- 它消除了对象模型周围复杂锐边的需要,如“元类”(我从来没有喜欢过元类......对不起!)或“特征值”等。
It has the following disadvantages however:
但是它有以下缺点:
- Type checking a prototype language isn't impossible, but it's very, very difficult. Most "type checking" of prototypical languages is pure run-time "duck typing"-style checks. This is not suitable to all environments.
- It is similarly difficult to do things like optimizing method dispatch by static (or, often, even dynamic!) analysis. It can(I stress: can) be very inefficient very easily.
- Similarly object creation can be (and usually is) much slower in a prototyping language than it can be in a more conventional class/object dichotomy scheme.
- 对原型语言进行类型检查并非不可能,但非常非常困难。大多数原型语言的“类型检查”是纯粹的运行时“鸭子类型”检查。这并不适合所有环境。
- 类似地,通过静态(或者,通常,甚至是动态!)分析来优化方法调度之类的事情也很困难。它可以(我强调:可以)很容易变得非常低效。
- 类似地,对象创建在原型语言中可能(并且通常)比在更传统的类/对象二分法方案中慢得多。
I think you can read between the lines above and come up with the corresponding advantages and disadvantages of traditional class/object schemes. There are, of course, more in each area so I'll leave the rest up to other people answering.
我想你可以从上面的字里行间读出来,并提出传统类/对象方案的相应优点和缺点。当然,每个领域都有更多的内容,所以我会将其余部分留给其他人来回答。
回答by CMS
IMO the major benefit of prototypal inheritance is its simplicity.
IMO 原型继承的主要好处是它的简单性。
The prototypal nature of the language can confuse people who are classicallytrained, but it turns out that actually this is a reallysimple and powerful concept, differential inheritance.
语言的原型性质可能会让受过经典训练的人感到困惑,但事实证明,这实际上是一个非常简单而强大的概念,差异继承。
You don't need to make classification, your code is smaller, less redundant, objects inherit from other, more general objects.
您不需要进行分类,您的代码更小,冗余更少,对象继承自其他更通用的对象。
If you think prototypicallyyou will soon notice that you don't need classes...
如果您按原型思考,您很快就会注意到您不需要类...
Prototypal inheritance will be much more popular in the near future, the ECMAScript 5th Editionspecification introduced the Object.createmethod, which allows you to produce a new object instance that inherits from another one in a really simple way:
原型继承在不久的将来会更加流行,ECMAScript 第 5 版规范引入了该Object.create方法,它允许您以一种非常简单的方式生成一个从另一个继承的新对象实例:
var obj = Object.create(baseInstance);
This new version of the standard is being implemented by all browser vendors, and I think we will start to see more pure prototypal inheritance...
这个新版本的标准正在由所有浏览器供应商实施,我认为我们将开始看到更多的纯原型继承......
回答by Noel Abrahams
There is really not a lot to choose between the two methods. The basic idea to grasp is that when the JavaScript engine is given a property of an object to read, it first checks the instance and if that property is missing, it checks up the prototype chain. Here is an example that shows the difference between prototypal and classical:
这两种方法之间真的没有太多选择。要掌握的基本思想是,当 JavaScript 引擎获得要读取的对象的属性时,它首先检查实例,如果缺少该属性,则检查原型链。这是一个示例,显示了原型和经典之间的区别:
Prototypal
原型
var single = { status: "Single" },
princeWilliam = Object.create(single),
cliffRichard = Object.create(single);
console.log(Object.keys(princeWilliam).length); // 0
console.log(Object.keys(cliffRichard).length); // 0
// Marriage event occurs
princeWilliam.status = "Married";
console.log(Object.keys(princeWilliam).length); // 1 (New instance property)
console.log(Object.keys(cliffRichard).length); // 0 (Still refers to prototype)
Classical with instance methods(Inefficient because each instance stores it's own property)
经典的实例方法(效率低下,因为每个实例都存储它自己的属性)
function Single() {
this.status = "Single";
}
var princeWilliam = new Single(),
cliffRichard = new Single();
console.log(Object.keys(princeWilliam).length); // 1
console.log(Object.keys(cliffRichard).length); // 1
Efficient classical
高效经典
function Single() {
}
Single.prototype.status = "Single";
var princeWilliam = new Single(),
cliffRichard = new Single();
princeWilliam.status = "Married";
console.log(Object.keys(princeWilliam).length); // 1
console.log(Object.keys(cliffRichard).length); // 0
console.log(cliffRichard.status); // "Single"
As you can see, since it is possible to manipulate the prototype of "classes" declared in the classical style, there is really no benefit to using prototypal inheritance. It is a subset of the classical method.
如您所见,由于可以操作以经典样式声明的“类”的原型,因此使用原型继承确实没有任何好处。它是经典方法的一个子集。
回答by ratty
Web Development: Prototypal Inheritance vs. Classical Inheritance
Web 开发:原型继承与经典继承
http://chamnapchhorn.blogspot.com/2009/05/prototypal-inheritance-vs-classical.html
http://chamnapchhorn.blogspot.com/2009/05/prototypal-inheritance-vs-classical.html
Classical Vs prototypal inheritance - Stack Overflow
经典与原型继承 - VoidCC

