下面针对 ES6 更新
2013 年 3 月和 ES5
这个 MDN 文档很好地描述了扩展类:
https://developer.mozilla.org/en-US/docs/JavaScript/Introduction_to_Object-Oriented_JavaScript
特别是,现在他们处理它:
// define the Person Class
function Person() {}
Person.prototype.walk = function(){
alert ('I am walking!');
};
Person.prototype.sayHello = function(){
alert ('hello');
};
// define the Student class
function Student() {
// Call the parent constructor
Person.call(this);
}
// inherit Person
Student.prototype = Object.create(Person.prototype);
// correct the constructor pointer because it points to Person
Student.prototype.constructor = Student;
// replace the sayHello method
Student.prototype.sayHello = function(){
alert('hi, I am a student');
}
// add sayGoodBye method
Student.prototype.sayGoodBye = function(){
alert('goodBye');
}
var student1 = new Student();
student1.sayHello();
student1.walk();
student1.sayGoodBye();
// check inheritance
alert(student1 instanceof Person); // true
alert(student1 instanceof Student); // true
请注意,Object.create()
某些旧浏览器不支持,包括 IE8:
如果您需要支持这些,链接的 MDN 文档建议使用 polyfill,或以下近似值:
function createObject(proto) {
function ctor() { }
ctor.prototype = proto;
return new ctor();
}
使用 this likeStudent.prototype = createObject(Person.prototype)
比使用更可取new Person()
,因为它避免在继承原型时调用父构造函数,并且仅在调用继承者的构造函数时调用父构造函数。
2017 年 5 月和 ES6
幸运的是,JavaScript 设计者听到了我们的求助,并采用了更合适的方式来解决这个问题。
MDN有另一个关于 ES6 类继承的很好的例子,但我将展示与上面在 ES6 中复制的完全相同的类集:
class Person {
sayHello() {
alert('hello');
}
walk() {
alert('I am walking!');
}
}
class Student extends Person {
sayGoodBye() {
alert('goodBye');
}
sayHello() {
alert('hi, I am a student');
}
}
var student1 = new Student();
student1.sayHello();
student1.walk();
student1.sayGoodBye();
// check inheritance
alert(student1 instanceof Person); // true
alert(student1 instanceof Student); // true
干净易懂,就像我们都想要的那样。请记住,虽然 ES6 很常见,但并非所有地方都支持: