Prototype copy vs Object.create()vs new [英] Prototype copy vs Object.create() vs new

查看:91
本文介绍了Prototype copy vs Object.create()vs new的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用继承,我注意到有三种方法可以获得相同的结果。有什么区别?

I was using inheritance and I noticed that there are three ways to get the same result. What's the difference?

function Animal(){
}

Animal.prototype.doThat = function() {
    document.write("Doing that");
}

function Bird(){
}

// This makes doThat() visible
Bird.prototype = Object.create(Animal.prototype); // Solution 1
// You can also do:
// Bird.prototype = new Animal(); // Solution 2
// Or:
// Bird.prototype = Animal.prototype; // Solution 3

var myVar = new Bird();
myVar.doThat();

如你所见,我提出了三个解决方案。他们中的每一个都使方法doThat()可见。

As you can see I proposed three solution. Each one of them make the method doThat() visible.

如果我评论所有这些确实存在错误。

If I comment all of them there is an error indeed.

如果我只取消其中一个程序有效。

If I decomment only one of them the program works.

那么......三种解决方案之间的区别是什么?

So... what's really the difference between the three solution?

推荐答案


Bird.prototype = Animal.prototype; //解决方案3

由于此指定 Animal.prototype 直接到 Bird.prototype ,你对后者所做的所有更改也会反映在 Animal 中其他继承自它的类。

Since this assigned Animal.prototype directly to Bird.prototype, all changes you make to the latter will also be reflected in Animal and all other classes that inherit from it.

例如:

Bird.prototype.fly = function() {
    console.log('I can fly.');
}

var some_animal = new Animal();
some_animal.fly(); // this will work

这肯定不是你想要的。此子类的每个方法不仅可用于其他子类,而且如果覆盖子类中的父方法,则最后定义的子类将覆盖其他子类的更改。

This is certainly not what you want. Not only will every method of this subclass available for other subclasses, but if you override parent methods in subclasses, the subclass that was defined last will override the changes of the other subclasses.

在您的问题标题中,您似乎将此称为原型副本。这是不正确的,因为没有创建副本。 Animal.prototype Bird.prototype 将引用同一个对象。

In your question title you seem to refer to this as "prototype copy". This is not correct, since no copy is created. Animal.prototype and Bird.prototype will refer to one and the same object.


Bird.prototype = new Animal(); //解决方案2

这是设置继承很长时间的常用方法,但它有两个主要缺点:

This has been a common way to setup inheritance for a long time but it has two major drawbacks:


  • 如果 Animal 需要参数,你通过了哪些参数?传递随机,毫无意义的参数只是为了使函数调用工作似乎是糟糕的设计。

  • Animal 可能有副作用,比如增加一个实例计数器,但是在这一刻你实际上没有创建一个新实例(或者不想),你只想设置继承。

  • If Animal requires arguments, which do you pass? Passing random, meaningless arguments just to make the function call work seems to be bad design.
  • Animal might have side effects, like increasing an instance counter, but in this moment you actually didn't create a new instance (or don't want to), you just wanted to setup the inheritance.

Bird.prototype = Object.create(Animal.prototype); //解决方案1 ​​

这就是你现在应该这样做的方式(直到找到更好的解决方案)。你真正想做的就是将 Animal 的原型连接到 Bird 的原型链中。它避免了以前解决方案的所有缺点。

That's the way you should do it now (until a better solution comes). All you really want to do is hook up Animal's prototype into the prototype chain of Bird. It avoids all the drawbacks of the previous solutions.

为了使其正常工作,您还必须调用 Animal Bird 构造函数中的构造函数。这就像在其他编程语言中调用 super 一样:

To make it work properly though, you also have to call the Animal constructor inside the Bird constructor. It's like a call to super in other programming languages:

function Bird(){
    Animal.call(this);
}

这可以确保对新的 Animal 实例应用于新的 Bird 实例。

This ensure that any commands/changes made to a new Animal instance are applied to the new Bird instance.

这也很好练习将正确的值分配给原型的构造函数属性。它通常是指原型属于的函数,但在上面的所有解决方案中, Bird.prototype.constructor 将引用 Animal 。所以我们必须这样做:

It is also good practice to assign the correct value to the constructor property of the prototype. It usually refers to the function the prototype "belongs to", but in all of the solutions above, Bird.prototype.constructor will refer to Animal. So we have to do:

Bird.prototype.constructor = Bird;

此属性未在内部使用,因此您只有必须执行此操作如果你自己的代码依赖它。但是,如果您创建一个供他人使用的库,他们可能会期望该属性必须更正值。

This property is not used internally, so you only have to do this if your own code relies on it. However, if you create a library to be used by others, they will probably expect the property to have to correct value.

这篇关于Prototype copy vs Object.create()vs new的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆