简体   繁体   English

通过原型继承JavaScript

[英]JavaScript inheritance through prototype

There is the most popular JavaScript method for inheritance: 有最流行的JavaScript继承方法:

function extend(Child, Parent) {
    var F = function() { }
    F.prototype = Parent.prototype;
    Child.prototype = new F();
    Child.prototype.constructor = Child;
    Child.superclass = Parent.prototype;
}

I'm learning JS now, but I have a lot of Java experience and this inheritance model seems some diffucult for me. 我现在正在学习JS,但是我有很多Java经验,这种继承模型对我来说似乎有些困难。 Why I can't do the following thing: 为什么我不能做以下事情:

function extend(Child, Parent) {
    Child.prototype = Parent.prototype; 
    Child.prototype.constructor = Child;
}

I think I don't know/understand some things, but F object is useless in my opinion. 我想我不知道/不了解某些事情,但是我认为F对象是没有用的。 Please, clarify the situation. 请澄清一下情况。 Thanks. 谢谢。

  Child.prototype = Parent.prototype; 

Now Child.prototype and Parent.prototype are the same object . 现在Child.prototypeParent.prototype同一个对象

Adding methods to Child.prototype will add them to Parent.prototype , which is not how classic OOP inheritance works. 将方法添加到Child.prototype会将它们添加到Parent.prototype ,这不是经典OOP继承的工作方式。

The most important thing to realize is that JavaScript does not have classical inheritance built in natively. 要意识到的最重要的事情是JavaScript没有本地内置的经典继承。 It is not like Java so you'll want to throw all your Java inheritance ideas right out the window if you want to work with JavaScript's prototypes. 它不像Java,因此,如果要使用JavaScript的原型,您将希望将所有Java继承想法丢到窗外。

The idea of a prototype is that you have a single object connected to a constructor function. 原型的想法是您将单个对象连接到构造函数。 That's your prototype object. 那是你的原型对象。 You use the constructor function to generate new objects that will all have access to the methods contained in the constructor's prototype. 您可以使用构造函数来生成新对象,这些对象都可以访问构造函数原型中包含的方法。 The trick is that if you ever modify the prototype attached to the constructor, the method you changed will now be changed for all child objects created by the constructor. 诀窍是,如果您曾经修改附加到构造函数的原型,则更改后的方法现在将针对构造函数创建的所有子对象而更改。 It works like this: 它的工作原理如下:

function Cat(name) {
    this.name = name;
}

Cat.prototype = {
  furColor: function () {
    return 'gray';
  }
};

var kitty1 = new Cat('Bob');
//=> {name: 'Bob'}

kitty1.furColor();
//=> 'gray'

Cat.prototype.furColor = function () {
  return 'white';
}

var kitty2 = new Cat('Sally');
//=> {name: 'Sally'}

kitty2.furColor();
//=> 'white'

kitty1.furColor();
//=> 'white'

So if you want to build classical inheritance off of this model you can, but just remember, this is what you get with prototypes in JavaScript. 因此,如果你想从这个模型构建经典继承,你可以,但请记住,这是你在JavaScript中使用原型获得的。

There's a pretty popular classical inheritance plugin that gives you some nice OO JavaScript called klass you might want to try instead of rolling your own. 有一个非常流行的经典继承插件,它为您提供了一些很好的OO JavaScript,称为klass,您可能想要尝试而不是自己滚动。

I believe that a javascript prototype is an actual instance of an object, and if you do something like: 我相信javascript prototype是一个对象的实际实例,如果你做了类似的事情:

Child.prototype = Parent.prototype; 
Child.prototype.constructor = Child;

you'll also be changing the Parent 's prototype too, because they're the same instance of an object. 你也将改变Parent的原型,因为它们是一个对象的同一个实例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM