理解 JavaScript 中的原型继承 [英] Understanding prototypal inheritance in JavaScript
问题描述
我是 JavaScript OOP 的新手.你能解释一下以下代码块之间的区别吗?我测试过,两个块都可以工作.最佳做法是什么?为什么?
I am new to JavaScript OOP. Can you please explain the difference between the following blocks of code? I tested and both blocks work. What's the best practice and why?
第一块:
function Car(name){
this.Name = name;
}
Car.prototype.Drive = function(){
console.log("My name is " + this.Name + " and I'm driving.");
}
SuperCar.prototype = new Car();
SuperCar.prototype.constructor = SuperCar;
function SuperCar(name){
Car.call(this, name);
}
SuperCar.prototype.Fly = function(){
console.log("My name is " + this.Name + " and I'm flying!");
}
var myCar = new Car("Car");
myCar.Drive();
var mySuperCar = new SuperCar("SuperCar");
mySuperCar.Drive();
mySuperCar.Fly();
第二块:
function Car(name){
this.Name = name;
this.Drive = function(){
console.log("My name is " + this.Name + " and I'm driving.");
}
}
SuperCar.prototype = new Car();
function SuperCar(name){
Car.call(this, name);
this.Fly = function(){
console.log("My name is " + this.Name + " and I'm flying!");
}
}
var myCar = new Car("Car");
myCar.Drive();
var mySuperCar = new SuperCar("SuperCar");
mySuperCar.Drive();
mySuperCar.Fly();
为什么作者使用prototype
添加了Drive
和Fly
方法,并且没有将它们声明为this.Drive
方法和 Car
类中的 SuperCar
类中的 this.Fly
?
Why did the author add the Drive
and Fly
methods using prototype
, and did not declare them as a this.Drive
method inside the Car
class and as this.Fly
in the SuperCar
class?
为什么SuperCar.prototype.constructor
需要设置回SuperCar
?设置 prototype
时是否覆盖了 constructor
属性?我注释掉了这一行,没有任何改变.
Why does SuperCar.prototype.constructor
need to be set back to SuperCar
? Is the constructor
property overridden when prototype
is set? I commented out this line and nothing changed.
为什么在SuperCar
构造函数中调用Car.call(this, name);
?当我这样做时,Car
的属性和方法不会被继承"
Why call Car.call(this, name);
in the SuperCar
constructor? Won't properties and methods of Car
be 'inherited' when I do
var myCar = new Car("Car");
推荐答案
这两个块的不同之处在于在第一个示例中 Drive()
将只存在一次,而在第二种方法中 Drive()
将存在于每个实例中(每次你执行 new Car()
函数 drive()
将再次创建).或者说第一个使用原型来存储函数,第二个使用构造函数.函数的查找是构造函数,然后是原型.因此,对于您对 Drive()
的查找,无论它是在构造函数中还是在原型中,它都会找到它.使用原型更有效,因为通常每个类型只需要一个函数.
The two blocks differ in a way that in the first example Drive()
will only exist once while at the second approach Drive()
will exist per instance (Every time you do new Car()
the function drive()
will be created again). Or different said the first uses the prototype to store the function and the second the constructor. The lookup for functions is constructor and then prototype. So for your lookup of Drive()
it finds it regardless if it is in the constructor or in the prototype. Using the prototype is more efficient because usually you need a function only once per type.
javascript 中的 new
调用会自动在原型中设置构造函数.如果要覆盖原型,则必须手动设置构造函数.
The new
call in javascript automatically sets the constructor in the prototype. If you are overwriting the prototype so you have to set the constructor manually.
javascript 中的继承与 super
完全不同.所以如果你有一个子类,调用超级构造函数的唯一机会就是通过它的名字.
Inheritance in javascript has nothing like super
. So if you have a subclass the only chance to call the super constructor is by its name.
这篇关于理解 JavaScript 中的原型继承的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!