In PHP/Java one can do:
在PHP/Java中,可以这样做:
class Sub extends Base
{
}
And automatically all public/protected methods, properties, fields, etc of the Super class become a part of the Sub class which can be overridden if necessary.
并且,超类的所有公共/受保护的方法、属性、字段等自动成为子类的一部分,必要时可以重写子类。
What's the equivalent for that in Javascript?
在Javascript中等价的是什么?
14 个解决方案
#1
76
I have changed how I do this now, I try to avoid using constructor functions and their prototype
property, but my old answer from 2010 is still at the bottom. I now prefer Object.create()
. Object.create
is available in all modern browsers.
我已经改变了我现在的做法,我试图避免使用构造函数和它们的原型属性,但是我在2010年的旧答案仍然在底部。我现在更喜欢Object.create()。对象。在所有现代浏览器中都可以使用create。
I should note that Object.create
is usually much slower than using new
with a function constructor.
我应该注意这个物体。create通常比在函数构造函数中使用new要慢得多。
//The prototype is just an object when you use `Object.create()`
var Base = {};
//This is how you create an instance:
var baseInstance = Object.create(Base);
//If you want to inherit from "Base":
var subInstance = Object.create(Object.create(Base));
//Detect if subInstance is an instance of Base:
console.log(Base.isPrototypeOf(subInstance)); //True
jsfiddle
One of the big benefits of using Object.create is being able to pass in a defineProperties argument, which gives you significant control over how properties on the class can be accessed and enumerated over, and I also use functions to create instances, these serve as constructors in a way, as you can do initialization at the end instead of just returning the instance.
使用对象的最大好处之一。创建能够通过defineProperties论点,它给你重要的控制属性的类可以访问和枚举,我也使用函数来创建实例,这些作为构造函数在某种程度上,你可以做初始化最后而不是返回实例。
var Base = {};
function createBase() {
return Object.create(Base, {
doSomething: {
value: function () {
console.log("Doing something");
},
},
});
}
var Sub = createBase();
function createSub() {
return Object.create(Sub, {
doSomethingElse: {
value: function () {
console.log("Doing something else");
},
},
});
}
var subInstance = createSub();
subInstance.doSomething(); //Logs "Doing something"
subInstance.doSomethingElse(); //Logs "Doing something else"
console.log(Base.isPrototypeOf(subInstance)); //Logs "true"
console.log(Sub.isPrototypeOf(subInstance)); //Logs "true
jsfiddle
This is my original answer from 2010:
这是我2010年的原始答案:
function Base ( ) {
this.color = "blue";
}
function Sub ( ) {
}
Sub.prototype = new Base( );
Sub.prototype.showColor = function ( ) {
console.log( this.color );
}
var instance = new Sub ( );
instance.showColor( ); //"blue"
#2
182
In JavaScript you don't have classes but you can get inheritance and behavior reuse in many ways:
在JavaScript中,你没有类,但是你可以通过很多方式获得继承和行为重用:
Pseudo-classical inheritance (through prototyping):
伪经典遗传(通过原型):
function Super () {
this.member1 = 'superMember1';
}
Super.prototype.member2 = 'superMember2';
function Sub() {
this.member3 = 'subMember3';
//...
}
Sub.prototype = new Super();
Should be used with the new
operator:
应与新操作员一起使用:
var subInstance = new Sub();
Function application or "constructor chaining":
函数应用程序或“构造函数链接”:
function Super () {
this.member1 = 'superMember1';
this.member2 = 'superMember2';
}
function Sub() {
Super.apply(this, arguments);
this.member3 = 'subMember3';
}
This approach should also be used with the new
operator:
新的操作员也应采用这种方法:
var subInstance = new Sub();
The difference with the first example is that when we apply
the Super
constructor to the this
object inside Sub
, it adds the properties assigned to this
on Super
, directly on the new instance, e.g. subInstance
contains the properties member1
and member2
directly (subInstance.hasOwnProperty('member1') == true;
).
与第一个示例的不同之处在于,当我们将超构造函数应用到子对象中时,它会直接在新实例(例如,subInstance. hasownproperty ('member1') = true;
In the first example, those properties are reached through the prototype chain, they exist on an internal [[Prototype]]
object.
在第一个示例中,这些属性通过原型链实现,它们存在于内部的[prototype]]对象上。
Parasitic inheritance or Power Constructors:
寄生遗传或权力建构者:
function createSuper() {
var obj = {
member1: 'superMember1',
member2: 'superMember2'
};
return obj;
}
function createSub() {
var obj = createSuper();
obj.member3 = 'subMember3';
return obj;
}
This approach is based basically on "object augmenting", you don't need to use the new
operator, and as you can see, the this
keyword is not involved.
这种方法基本上基于“对象扩充”,您不需要使用新的操作符,正如您所看到的,不涉及这个关键字。
var subInstance = createSub();
ECMAScript 5th Ed. Object.create
method:
ECMAScript 5。对象。创建方法:
// Check if native implementation available
if (typeof Object.create !== 'function') {
Object.create = function (o) {
function F() {} // empty constructor
F.prototype = o; // set base object as prototype
return new F(); // return empty object with right [[Prototype]]
};
}
var superInstance = {
member1: 'superMember1',
member2: 'superMember2'
};
var subInstance = Object.create(superInstance);
subInstance.member3 = 'subMember3';
The above method is a prototypal inheritance technique proposed by Crockford.
上述方法是Crockford提出的一种原型继承技术。
Object instances inherit from other object instances, that's it.
对象实例从其他对象实例继承,就是这样。
This technique can be better than simple "object augmentation" because the inherited properties aren't copied over all the new object instances, since the base object is set as the [[Prototype]]
of the extended object, in the above example subInstance
contains physically only the member3
property.
这种技术比简单的“对象扩展”要好,因为继承的属性不会在所有新对象实例上复制,因为基本对象被设置为扩展对象的[Prototype],在上面的示例子实例中,物理上只包含member3属性。
#3
38
For those who reach this page in 2015 or after
With the latest version of the ECMAScript standard (ES6), you can use de keywork extends
使用最新版本的ECMAScript标准(ES6),您可以使用de keywork扩展
Note that the class definition is not a regular object
hence, there are no commas between class members. To create an instance of a class, you must use the new
keyword. To inherit from a base class, use extends
:
注意,类定义不是一个常规对象,因此,类成员之间没有逗号。要创建类的实例,必须使用new关键字。要从基类继承,请使用extend:
class Vehicle {
constructor(name) {
this.name = name;
this.kind = 'vehicle';
}
getName() {
return this.name;
}
}
// Create an instance
var myVehicle = new Vehicle('rocky');
myVehicle.getName(); // => 'rocky'
To inherit from a base class, use extends
:
要从基类继承,请使用extend:
class Car extends Vehicle {
constructor(name) {
super(name);
this.kind = 'car'
}
}
var myCar = new Car('bumpy');
myCar.getName(); // => 'bumpy'
myCar instanceof Car; // => true
myCar instanceof Vehicle; // => true
From the derived class, you can use super from any constructor or method to access its base class:
从派生类中,可以使用任何构造函数或方法的super来访问其基类:
- To call the parent constructor, use
super().
- 要调用父构造函数,请使用super()。
- To call another member, use, for example,
super.getName()
. - 要调用另一个成员,请使用super.getName()。
There’s more to using classes. If you want to dig deeper into the subject, I recommend “Classes in ECMAScript 6” by Dr. Axel Rauschmayer.*
使用类还有更多内容。如果你想深入研究这个主题,我推荐Axel Rauschmayer博士的《ECMAScript 6中的课程》*
源
#4
7
Well, in JavaScript there is no "class inheritance", there is just "prototype inheritance". So you don't make a class "truck" and then mark it as a subclass of "automobile". Instead, you make an object "Jack" and say that it uses "John" as a prototype. If John knows, how much "4+4" is, then Jack knows it, too.
在JavaScript中没有“类继承”,只有“原型继承”。所以你不会把一个类叫做“卡车”然后把它标记为“汽车”的子类。相反,你制作一个“Jack”对象,并说它使用“John”作为原型。如果约翰知道,4+4是多少,杰克也知道。
I suggest you read Douglas Crockford's article about prototypal inheritance here: http://javascript.crockford.com/prototypal.html He also shows how you can make JavaScript have "look-alike" inheritance as in other OO languages and then explains that this actually means breaking javaScript in a way it was not meant to be used.
我建议您阅读Douglas Crockford关于原型继承的文章:http://javascript.crockford.com/prototypal.html,他还展示了如何使JavaScript具有与其他OO语言类似的“外观”继承,然后解释说,这实际上意味着以一种不应该使用的方式破坏JavaScript。
#5
6
I find this quote to be the most enlightening:
我发现这句话最有启发性:
In essence, a JavaScript "class" is just a Function object that serves as a constructor plus an attached prototype object. (Source: Guru Katz)
本质上,一个JavaScript“类”只是一个函数对象,它充当构造函数和附加的原型对象。(来源:大师Katz)
I like using constructors rather than objects, so I'm partial to the "pseudo-classical inheritance" method described here by CMS. Here is an example of multiple inheritance with a prototype chain:
我喜欢使用构造函数而不是对象,所以我偏爱CMS描述的“伪经典继承”方法。下面是一个带有原型链的多重继承示例:
// Lifeform "Class" (Constructor function, No prototype)
function Lifeform () {
this.isLifeform = true;
}
// Animal "Class" (Constructor function + prototype for inheritance)
function Animal () {
this.isAnimal = true;
}
Animal.prototype = new Lifeform();
// Mammal "Class" (Constructor function + prototype for inheritance)
function Mammal () {
this.isMammal = true;
}
Mammal.prototype = new Animal();
// Cat "Class" (Constructor function + prototype for inheritance)
function Cat (species) {
this.isCat = true;
this.species = species
}
Cat.prototype = new Mammal();
// Make an instance object of the Cat "Class"
var tiger = new Cat("tiger");
console.log(tiger);
// The console outputs a Cat object with all the properties from all "classes"
console.log(tiger.isCat, tiger.isMammal, tiger.isAnimal, tiger.isLifeform);
// Outputs: true true true true
// You can see that all of these "is" properties are available in this object
// We can check to see which properties are really part of the instance object
console.log( "tiger hasOwnProperty: "
,tiger.hasOwnProperty("isLifeform") // false
,tiger.hasOwnProperty("isAnimal") // false
,tiger.hasOwnProperty("isMammal") // false
,tiger.hasOwnProperty("isCat") // true
);
// New properties can be added to the prototypes of any
// of the "classes" above and they will be usable by the instance
Lifeform.prototype.A = 1;
Animal.prototype.B = 2;
Mammal.prototype.C = 3;
Cat.prototype.D = 4;
console.log(tiger.A, tiger.B, tiger.C, tiger.D);
// Console outputs: 1 2 3 4
// Look at the instance object again
console.log(tiger);
// You'll see it now has the "D" property
// The others are accessible but not visible (console issue?)
// In the Chrome console you should be able to drill down the __proto__ chain
// You can also look down the proto chain with Object.getPrototypeOf
// (Equivalent to tiger.__proto__)
console.log( Object.getPrototypeOf(tiger) ); // Mammal
console.log( Object.getPrototypeOf(Object.getPrototypeOf(tiger)) ); // Animal
// Etc. to get to Lifeform
Here is another good resource from MDN, and here is a jsfiddle so you can try it out.
这是来自MDN的另一个很好的资源,这是一个jsfiddle,您可以试用它。
#6
4
Javascript inheritance is a bit different from Java and PHP, because it doesn't really have classes. Instead it has prototype objects that provide methods and member variables. You can chain those prototypes to provide object inheritance. The most common pattern I found when researching this question is described on the Mozilla Developer Network. I've updated their example to include a call to a superclass method and to show the log in an alert message:
Javascript继承与Java和PHP稍有不同,因为它实际上没有类。相反,它拥有提供方法和成员变量的原型对象。您可以链接这些原型来提供对象继承。我在研究这个问题时发现的最常见的模式是Mozilla开发人员网络。我更新了他们的示例,包括对超类方法的调用,并在警告消息中显示日志:
// Shape - superclass
function Shape() {
this.x = 0;
this.y = 0;
}
// superclass method
Shape.prototype.move = function(x, y) {
this.x += x;
this.y += y;
log += 'Shape moved.\n';
};
// Rectangle - subclass
function Rectangle() {
Shape.call(this); // call super constructor.
}
// subclass extends superclass
Rectangle.prototype = Object.create(Shape.prototype);
Rectangle.prototype.constructor = Rectangle;
// Override method
Rectangle.prototype.move = function(x, y) {
Shape.prototype.move.call(this, x, y); // call superclass method
log += 'Rectangle moved.\n';
}
var log = "";
var rect = new Rectangle();
log += ('Is rect an instance of Rectangle? ' + (rect instanceof Rectangle) + '\n'); // true
log += ('Is rect an instance of Shape? ' + (rect instanceof Shape) + '\n'); // true
rect.move(1, 1); // Outputs, 'Shape moved.'
alert(log);
Personally, I find inheritance in Javascript awkward, but this is the best version I've found.
就我个人而言,我觉得Javascript中的继承很尴尬,但这是我找到的最好的版本。
#7
3
you can't (in the classical sense). Javascript is a prototypical language. You will observe that you never declare a "class" in Javascript; you merely define the state and methods of an object. To produce inheritance, you take some object and prototype it. The prototype is extended with new functionality.
你不能(在古典意义上)。Javascript是一种典型的语言。您将注意到,您从未在Javascript中声明“类”;您只需定义对象的状态和方法。要生成继承,需要获取一些对象并对其进行原型。原型扩展了新的功能。
#8
1
You can use .inheritWith
and .fastClass
library. It is faster than most popular libraries and sometimes even faster than the native version.
可以使用。继承和。fastclass库。它比大多数流行的库要快,有时甚至比本地版本还要快。
Very easy to use:
非常易于使用:
function Super() {
this.member1 = "superMember";//instance member
}.define({ //define methods on Super's prototype
method1: function() { console.log('super'); } //prototype member
}.defineStatic({ //define static methods directly on Super function
staticMethod1: function() { console.log('static method on Super'); }
});
var Sub = Super.inheritWith(function(base, baseCtor) {
return {
constructor: function() {//the Sub constructor that will be returned to variable Sub
this.member3 = 'subMember3'; //instance member on Sub
baseCtor.apply(this, arguments);//call base construcor and passing all incoming arguments
},
method1: function() {
console.log('sub');
base.method1.apply(this, arguments); //call the base class' method1 function
}
}
Usage
使用
var s = new Sub();
s.method1(); //prints:
//sub
//super
#9
1
After reading many posts, i came up with this solution (jsfiddle here). Most of the time i don't need something more sophisticated
在阅读了许多文章之后,我提出了这个解决方案(jsfiddle)。大多数时候我不需要更复杂的东西
var Class = function(definition) {
var base = definition.extend || null;
var construct = definition.construct || definition.extend || function() {};
var newClass = function() {
this._base_ = base;
construct.apply(this, arguments);
}
if (definition.name)
newClass._name_ = definition.name;
if (definition.extend) {
var f = function() {}
f.prototype = definition.extend.prototype;
newClass.prototype = new f();
newClass.prototype.constructor = newClass;
newClass._extend_ = definition.extend;
newClass._base_ = definition.extend.prototype;
}
if (definition.statics)
for (var n in definition.statics) newClass[n] = definition.statics[n];
if (definition.members)
for (var n in definition.members) newClass.prototype[n] = definition.members[n];
return newClass;
}
var Animal = Class({
construct: function() {
},
members: {
speak: function() {
console.log("nuf said");
},
isA: function() {
return "animal";
}
}
});
var Dog = Class({ extend: Animal,
construct: function(name) {
this._base_();
this.name = name;
},
statics: {
Home: "House",
Food: "Meat",
Speak: "Barks"
},
members: {
name: "",
speak: function() {
console.log( "ouaf !");
},
isA: function(advice) {
return advice + " dog -> " + Dog._base_.isA.call(this);
}
}
});
var Yorkshire = Class({ extend: Dog,
construct: function(name,gender) {
this._base_(name);
this.gender = gender;
},
members: {
speak: function() {
console.log( "ouin !");
},
isA: function(advice) {
return "yorkshire -> " + Yorkshire._base_.isA.call(this,advice);
}
}
});
var Bulldog = function() { return _class_ = Class({ extend: Dog,
construct: function(name) {
this._base_(name);
},
members: {
speak: function() {
console.log( "OUAF !");
},
isA: function(advice) {
return "bulldog -> " + _class_._base_.isA.call(this,advice);
}
}
})}();
var animal = new Animal("Maciste");
console.log(animal.isA());
animal.speak();
var dog = new Dog("Sultan");
console.log(dog.isA("good"));
dog.speak();
var yorkshire = new Yorkshire("Golgoth","Male");
console.log(yorkshire.isA("bad"));
yorkshire.speak();
var bulldog = new Bulldog("Mike");
console.log(bulldog.isA("nice"));
bulldog.speak();
#10
1
Thanks to CMS's answer and after fiddling for a while with prototype and Object.create and what not, I was able to come up with a neat solution for my inheritance using apply as shown here:
感谢CMS的回答,在修改了原型和对象之后。create和什么的,我可以用apply为我的继承想出一个简洁的解决方案,如下所示:
var myNamespace = myNamespace || (function() {
return {
BaseClass: function(){
this.someBaseProperty = "someBaseProperty";
this.someProperty = "BaseClass";
this.someFunc = null;
},
DerivedClass:function(someFunc){
myNamespace.BaseClass.apply(this, arguments);
this.someFunc = someFunc;
this.someProperty = "DerivedClass";
},
MoreDerivedClass:function(someFunc){
myNamespace.DerivedClass.apply(this, arguments);
this.someFunc = someFunc;
this.someProperty = "MoreDerivedClass";
}
};
})();
#11
1
From ES2015, that's exactly how you do inheritance in JavaScript
从ES2015开始,这就是如何在JavaScript中进行继承
class Sub extends Base {
}
- https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Classes
- https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Classes
- http://exploringjs.com/es6/ch_classes.html
- http://exploringjs.com/es6/ch_classes.html
#12
0
You can't inherit from a class in JavaScript, because there are no classes in JavaScript.
不能从JavaScript中继承类,因为JavaScript中没有类。
#13
0
function Person(attr){
this.name = (attr && attr.name)? attr.name : undefined;
this.birthYear = (attr && attr.birthYear)? attr.birthYear : undefined;
this.printName = function(){
console.log(this.name);
}
this.printBirthYear = function(){
console.log(this.birthYear);
}
this.print = function(){
console.log(this.name + '(' +this.birthYear+ ')');
}
}
function PersonExt(attr){
Person.call(this, attr);
this.print = function(){
console.log(this.name+ '-' + this.birthYear);
}
this.newPrint = function(){
console.log('New method');
}
}
PersonExt.prototype = new Person();
// Init object and call methods
var p = new Person({name: 'Mr. A', birthYear: 2007});
// Parent method
p.print() // Mr. A(2007)
p.printName() // Mr. A
var pExt = new PersonExt({name: 'Mr. A', birthYear: 2007});
// Overwriten method
pExt.print() // Mr. A-2007
// Extended method
pExt.newPrint() // New method
// Parent method
pExt.printName() // Mr. A
#14
0
function Base() {
this.doSomething = function () {
}
}
function Sub() {
Base.call(this); // inherit Base's method(s) to this instance of Sub
}
var sub = new Sub();
sub.doSomething();
#1
76
I have changed how I do this now, I try to avoid using constructor functions and their prototype
property, but my old answer from 2010 is still at the bottom. I now prefer Object.create()
. Object.create
is available in all modern browsers.
我已经改变了我现在的做法,我试图避免使用构造函数和它们的原型属性,但是我在2010年的旧答案仍然在底部。我现在更喜欢Object.create()。对象。在所有现代浏览器中都可以使用create。
I should note that Object.create
is usually much slower than using new
with a function constructor.
我应该注意这个物体。create通常比在函数构造函数中使用new要慢得多。
//The prototype is just an object when you use `Object.create()`
var Base = {};
//This is how you create an instance:
var baseInstance = Object.create(Base);
//If you want to inherit from "Base":
var subInstance = Object.create(Object.create(Base));
//Detect if subInstance is an instance of Base:
console.log(Base.isPrototypeOf(subInstance)); //True
jsfiddle
One of the big benefits of using Object.create is being able to pass in a defineProperties argument, which gives you significant control over how properties on the class can be accessed and enumerated over, and I also use functions to create instances, these serve as constructors in a way, as you can do initialization at the end instead of just returning the instance.
使用对象的最大好处之一。创建能够通过defineProperties论点,它给你重要的控制属性的类可以访问和枚举,我也使用函数来创建实例,这些作为构造函数在某种程度上,你可以做初始化最后而不是返回实例。
var Base = {};
function createBase() {
return Object.create(Base, {
doSomething: {
value: function () {
console.log("Doing something");
},
},
});
}
var Sub = createBase();
function createSub() {
return Object.create(Sub, {
doSomethingElse: {
value: function () {
console.log("Doing something else");
},
},
});
}
var subInstance = createSub();
subInstance.doSomething(); //Logs "Doing something"
subInstance.doSomethingElse(); //Logs "Doing something else"
console.log(Base.isPrototypeOf(subInstance)); //Logs "true"
console.log(Sub.isPrototypeOf(subInstance)); //Logs "true
jsfiddle
This is my original answer from 2010:
这是我2010年的原始答案:
function Base ( ) {
this.color = "blue";
}
function Sub ( ) {
}
Sub.prototype = new Base( );
Sub.prototype.showColor = function ( ) {
console.log( this.color );
}
var instance = new Sub ( );
instance.showColor( ); //"blue"
#2
182
In JavaScript you don't have classes but you can get inheritance and behavior reuse in many ways:
在JavaScript中,你没有类,但是你可以通过很多方式获得继承和行为重用:
Pseudo-classical inheritance (through prototyping):
伪经典遗传(通过原型):
function Super () {
this.member1 = 'superMember1';
}
Super.prototype.member2 = 'superMember2';
function Sub() {
this.member3 = 'subMember3';
//...
}
Sub.prototype = new Super();
Should be used with the new
operator:
应与新操作员一起使用:
var subInstance = new Sub();
Function application or "constructor chaining":
函数应用程序或“构造函数链接”:
function Super () {
this.member1 = 'superMember1';
this.member2 = 'superMember2';
}
function Sub() {
Super.apply(this, arguments);
this.member3 = 'subMember3';
}
This approach should also be used with the new
operator:
新的操作员也应采用这种方法:
var subInstance = new Sub();
The difference with the first example is that when we apply
the Super
constructor to the this
object inside Sub
, it adds the properties assigned to this
on Super
, directly on the new instance, e.g. subInstance
contains the properties member1
and member2
directly (subInstance.hasOwnProperty('member1') == true;
).
与第一个示例的不同之处在于,当我们将超构造函数应用到子对象中时,它会直接在新实例(例如,subInstance. hasownproperty ('member1') = true;
In the first example, those properties are reached through the prototype chain, they exist on an internal [[Prototype]]
object.
在第一个示例中,这些属性通过原型链实现,它们存在于内部的[prototype]]对象上。
Parasitic inheritance or Power Constructors:
寄生遗传或权力建构者:
function createSuper() {
var obj = {
member1: 'superMember1',
member2: 'superMember2'
};
return obj;
}
function createSub() {
var obj = createSuper();
obj.member3 = 'subMember3';
return obj;
}
This approach is based basically on "object augmenting", you don't need to use the new
operator, and as you can see, the this
keyword is not involved.
这种方法基本上基于“对象扩充”,您不需要使用新的操作符,正如您所看到的,不涉及这个关键字。
var subInstance = createSub();
ECMAScript 5th Ed. Object.create
method:
ECMAScript 5。对象。创建方法:
// Check if native implementation available
if (typeof Object.create !== 'function') {
Object.create = function (o) {
function F() {} // empty constructor
F.prototype = o; // set base object as prototype
return new F(); // return empty object with right [[Prototype]]
};
}
var superInstance = {
member1: 'superMember1',
member2: 'superMember2'
};
var subInstance = Object.create(superInstance);
subInstance.member3 = 'subMember3';
The above method is a prototypal inheritance technique proposed by Crockford.
上述方法是Crockford提出的一种原型继承技术。
Object instances inherit from other object instances, that's it.
对象实例从其他对象实例继承,就是这样。
This technique can be better than simple "object augmentation" because the inherited properties aren't copied over all the new object instances, since the base object is set as the [[Prototype]]
of the extended object, in the above example subInstance
contains physically only the member3
property.
这种技术比简单的“对象扩展”要好,因为继承的属性不会在所有新对象实例上复制,因为基本对象被设置为扩展对象的[Prototype],在上面的示例子实例中,物理上只包含member3属性。
#3
38
For those who reach this page in 2015 or after
With the latest version of the ECMAScript standard (ES6), you can use de keywork extends
使用最新版本的ECMAScript标准(ES6),您可以使用de keywork扩展
Note that the class definition is not a regular object
hence, there are no commas between class members. To create an instance of a class, you must use the new
keyword. To inherit from a base class, use extends
:
注意,类定义不是一个常规对象,因此,类成员之间没有逗号。要创建类的实例,必须使用new关键字。要从基类继承,请使用extend:
class Vehicle {
constructor(name) {
this.name = name;
this.kind = 'vehicle';
}
getName() {
return this.name;
}
}
// Create an instance
var myVehicle = new Vehicle('rocky');
myVehicle.getName(); // => 'rocky'
To inherit from a base class, use extends
:
要从基类继承,请使用extend:
class Car extends Vehicle {
constructor(name) {
super(name);
this.kind = 'car'
}
}
var myCar = new Car('bumpy');
myCar.getName(); // => 'bumpy'
myCar instanceof Car; // => true
myCar instanceof Vehicle; // => true
From the derived class, you can use super from any constructor or method to access its base class:
从派生类中,可以使用任何构造函数或方法的super来访问其基类:
- To call the parent constructor, use
super().
- 要调用父构造函数,请使用super()。
- To call another member, use, for example,
super.getName()
. - 要调用另一个成员,请使用super.getName()。
There’s more to using classes. If you want to dig deeper into the subject, I recommend “Classes in ECMAScript 6” by Dr. Axel Rauschmayer.*
使用类还有更多内容。如果你想深入研究这个主题,我推荐Axel Rauschmayer博士的《ECMAScript 6中的课程》*
源
#4
7
Well, in JavaScript there is no "class inheritance", there is just "prototype inheritance". So you don't make a class "truck" and then mark it as a subclass of "automobile". Instead, you make an object "Jack" and say that it uses "John" as a prototype. If John knows, how much "4+4" is, then Jack knows it, too.
在JavaScript中没有“类继承”,只有“原型继承”。所以你不会把一个类叫做“卡车”然后把它标记为“汽车”的子类。相反,你制作一个“Jack”对象,并说它使用“John”作为原型。如果约翰知道,4+4是多少,杰克也知道。
I suggest you read Douglas Crockford's article about prototypal inheritance here: http://javascript.crockford.com/prototypal.html He also shows how you can make JavaScript have "look-alike" inheritance as in other OO languages and then explains that this actually means breaking javaScript in a way it was not meant to be used.
我建议您阅读Douglas Crockford关于原型继承的文章:http://javascript.crockford.com/prototypal.html,他还展示了如何使JavaScript具有与其他OO语言类似的“外观”继承,然后解释说,这实际上意味着以一种不应该使用的方式破坏JavaScript。
#5
6
I find this quote to be the most enlightening:
我发现这句话最有启发性:
In essence, a JavaScript "class" is just a Function object that serves as a constructor plus an attached prototype object. (Source: Guru Katz)
本质上,一个JavaScript“类”只是一个函数对象,它充当构造函数和附加的原型对象。(来源:大师Katz)
I like using constructors rather than objects, so I'm partial to the "pseudo-classical inheritance" method described here by CMS. Here is an example of multiple inheritance with a prototype chain:
我喜欢使用构造函数而不是对象,所以我偏爱CMS描述的“伪经典继承”方法。下面是一个带有原型链的多重继承示例:
// Lifeform "Class" (Constructor function, No prototype)
function Lifeform () {
this.isLifeform = true;
}
// Animal "Class" (Constructor function + prototype for inheritance)
function Animal () {
this.isAnimal = true;
}
Animal.prototype = new Lifeform();
// Mammal "Class" (Constructor function + prototype for inheritance)
function Mammal () {
this.isMammal = true;
}
Mammal.prototype = new Animal();
// Cat "Class" (Constructor function + prototype for inheritance)
function Cat (species) {
this.isCat = true;
this.species = species
}
Cat.prototype = new Mammal();
// Make an instance object of the Cat "Class"
var tiger = new Cat("tiger");
console.log(tiger);
// The console outputs a Cat object with all the properties from all "classes"
console.log(tiger.isCat, tiger.isMammal, tiger.isAnimal, tiger.isLifeform);
// Outputs: true true true true
// You can see that all of these "is" properties are available in this object
// We can check to see which properties are really part of the instance object
console.log( "tiger hasOwnProperty: "
,tiger.hasOwnProperty("isLifeform") // false
,tiger.hasOwnProperty("isAnimal") // false
,tiger.hasOwnProperty("isMammal") // false
,tiger.hasOwnProperty("isCat") // true
);
// New properties can be added to the prototypes of any
// of the "classes" above and they will be usable by the instance
Lifeform.prototype.A = 1;
Animal.prototype.B = 2;
Mammal.prototype.C = 3;
Cat.prototype.D = 4;
console.log(tiger.A, tiger.B, tiger.C, tiger.D);
// Console outputs: 1 2 3 4
// Look at the instance object again
console.log(tiger);
// You'll see it now has the "D" property
// The others are accessible but not visible (console issue?)
// In the Chrome console you should be able to drill down the __proto__ chain
// You can also look down the proto chain with Object.getPrototypeOf
// (Equivalent to tiger.__proto__)
console.log( Object.getPrototypeOf(tiger) ); // Mammal
console.log( Object.getPrototypeOf(Object.getPrototypeOf(tiger)) ); // Animal
// Etc. to get to Lifeform
Here is another good resource from MDN, and here is a jsfiddle so you can try it out.
这是来自MDN的另一个很好的资源,这是一个jsfiddle,您可以试用它。
#6
4
Javascript inheritance is a bit different from Java and PHP, because it doesn't really have classes. Instead it has prototype objects that provide methods and member variables. You can chain those prototypes to provide object inheritance. The most common pattern I found when researching this question is described on the Mozilla Developer Network. I've updated their example to include a call to a superclass method and to show the log in an alert message:
Javascript继承与Java和PHP稍有不同,因为它实际上没有类。相反,它拥有提供方法和成员变量的原型对象。您可以链接这些原型来提供对象继承。我在研究这个问题时发现的最常见的模式是Mozilla开发人员网络。我更新了他们的示例,包括对超类方法的调用,并在警告消息中显示日志:
// Shape - superclass
function Shape() {
this.x = 0;
this.y = 0;
}
// superclass method
Shape.prototype.move = function(x, y) {
this.x += x;
this.y += y;
log += 'Shape moved.\n';
};
// Rectangle - subclass
function Rectangle() {
Shape.call(this); // call super constructor.
}
// subclass extends superclass
Rectangle.prototype = Object.create(Shape.prototype);
Rectangle.prototype.constructor = Rectangle;
// Override method
Rectangle.prototype.move = function(x, y) {
Shape.prototype.move.call(this, x, y); // call superclass method
log += 'Rectangle moved.\n';
}
var log = "";
var rect = new Rectangle();
log += ('Is rect an instance of Rectangle? ' + (rect instanceof Rectangle) + '\n'); // true
log += ('Is rect an instance of Shape? ' + (rect instanceof Shape) + '\n'); // true
rect.move(1, 1); // Outputs, 'Shape moved.'
alert(log);
Personally, I find inheritance in Javascript awkward, but this is the best version I've found.
就我个人而言,我觉得Javascript中的继承很尴尬,但这是我找到的最好的版本。
#7
3
you can't (in the classical sense). Javascript is a prototypical language. You will observe that you never declare a "class" in Javascript; you merely define the state and methods of an object. To produce inheritance, you take some object and prototype it. The prototype is extended with new functionality.
你不能(在古典意义上)。Javascript是一种典型的语言。您将注意到,您从未在Javascript中声明“类”;您只需定义对象的状态和方法。要生成继承,需要获取一些对象并对其进行原型。原型扩展了新的功能。
#8
1
You can use .inheritWith
and .fastClass
library. It is faster than most popular libraries and sometimes even faster than the native version.
可以使用。继承和。fastclass库。它比大多数流行的库要快,有时甚至比本地版本还要快。
Very easy to use:
非常易于使用:
function Super() {
this.member1 = "superMember";//instance member
}.define({ //define methods on Super's prototype
method1: function() { console.log('super'); } //prototype member
}.defineStatic({ //define static methods directly on Super function
staticMethod1: function() { console.log('static method on Super'); }
});
var Sub = Super.inheritWith(function(base, baseCtor) {
return {
constructor: function() {//the Sub constructor that will be returned to variable Sub
this.member3 = 'subMember3'; //instance member on Sub
baseCtor.apply(this, arguments);//call base construcor and passing all incoming arguments
},
method1: function() {
console.log('sub');
base.method1.apply(this, arguments); //call the base class' method1 function
}
}
Usage
使用
var s = new Sub();
s.method1(); //prints:
//sub
//super
#9
1
After reading many posts, i came up with this solution (jsfiddle here). Most of the time i don't need something more sophisticated
在阅读了许多文章之后,我提出了这个解决方案(jsfiddle)。大多数时候我不需要更复杂的东西
var Class = function(definition) {
var base = definition.extend || null;
var construct = definition.construct || definition.extend || function() {};
var newClass = function() {
this._base_ = base;
construct.apply(this, arguments);
}
if (definition.name)
newClass._name_ = definition.name;
if (definition.extend) {
var f = function() {}
f.prototype = definition.extend.prototype;
newClass.prototype = new f();
newClass.prototype.constructor = newClass;
newClass._extend_ = definition.extend;
newClass._base_ = definition.extend.prototype;
}
if (definition.statics)
for (var n in definition.statics) newClass[n] = definition.statics[n];
if (definition.members)
for (var n in definition.members) newClass.prototype[n] = definition.members[n];
return newClass;
}
var Animal = Class({
construct: function() {
},
members: {
speak: function() {
console.log("nuf said");
},
isA: function() {
return "animal";
}
}
});
var Dog = Class({ extend: Animal,
construct: function(name) {
this._base_();
this.name = name;
},
statics: {
Home: "House",
Food: "Meat",
Speak: "Barks"
},
members: {
name: "",
speak: function() {
console.log( "ouaf !");
},
isA: function(advice) {
return advice + " dog -> " + Dog._base_.isA.call(this);
}
}
});
var Yorkshire = Class({ extend: Dog,
construct: function(name,gender) {
this._base_(name);
this.gender = gender;
},
members: {
speak: function() {
console.log( "ouin !");
},
isA: function(advice) {
return "yorkshire -> " + Yorkshire._base_.isA.call(this,advice);
}
}
});
var Bulldog = function() { return _class_ = Class({ extend: Dog,
construct: function(name) {
this._base_(name);
},
members: {
speak: function() {
console.log( "OUAF !");
},
isA: function(advice) {
return "bulldog -> " + _class_._base_.isA.call(this,advice);
}
}
})}();
var animal = new Animal("Maciste");
console.log(animal.isA());
animal.speak();
var dog = new Dog("Sultan");
console.log(dog.isA("good"));
dog.speak();
var yorkshire = new Yorkshire("Golgoth","Male");
console.log(yorkshire.isA("bad"));
yorkshire.speak();
var bulldog = new Bulldog("Mike");
console.log(bulldog.isA("nice"));
bulldog.speak();
#10
1
Thanks to CMS's answer and after fiddling for a while with prototype and Object.create and what not, I was able to come up with a neat solution for my inheritance using apply as shown here:
感谢CMS的回答,在修改了原型和对象之后。create和什么的,我可以用apply为我的继承想出一个简洁的解决方案,如下所示:
var myNamespace = myNamespace || (function() {
return {
BaseClass: function(){
this.someBaseProperty = "someBaseProperty";
this.someProperty = "BaseClass";
this.someFunc = null;
},
DerivedClass:function(someFunc){
myNamespace.BaseClass.apply(this, arguments);
this.someFunc = someFunc;
this.someProperty = "DerivedClass";
},
MoreDerivedClass:function(someFunc){
myNamespace.DerivedClass.apply(this, arguments);
this.someFunc = someFunc;
this.someProperty = "MoreDerivedClass";
}
};
})();
#11
1
From ES2015, that's exactly how you do inheritance in JavaScript
从ES2015开始,这就是如何在JavaScript中进行继承
class Sub extends Base {
}
- https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Classes
- https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Classes
- http://exploringjs.com/es6/ch_classes.html
- http://exploringjs.com/es6/ch_classes.html
#12
0
You can't inherit from a class in JavaScript, because there are no classes in JavaScript.
不能从JavaScript中继承类,因为JavaScript中没有类。
#13
0
function Person(attr){
this.name = (attr && attr.name)? attr.name : undefined;
this.birthYear = (attr && attr.birthYear)? attr.birthYear : undefined;
this.printName = function(){
console.log(this.name);
}
this.printBirthYear = function(){
console.log(this.birthYear);
}
this.print = function(){
console.log(this.name + '(' +this.birthYear+ ')');
}
}
function PersonExt(attr){
Person.call(this, attr);
this.print = function(){
console.log(this.name+ '-' + this.birthYear);
}
this.newPrint = function(){
console.log('New method');
}
}
PersonExt.prototype = new Person();
// Init object and call methods
var p = new Person({name: 'Mr. A', birthYear: 2007});
// Parent method
p.print() // Mr. A(2007)
p.printName() // Mr. A
var pExt = new PersonExt({name: 'Mr. A', birthYear: 2007});
// Overwriten method
pExt.print() // Mr. A-2007
// Extended method
pExt.newPrint() // New method
// Parent method
pExt.printName() // Mr. A
#14
0
function Base() {
this.doSomething = function () {
}
}
function Sub() {
Base.call(this); // inherit Base's method(s) to this instance of Sub
}
var sub = new Sub();
sub.doSomething();