很多js框架都定义了js继承 各种extend 对于 js对象继承更倾向于用官方提供的写法,当然 你 可以封装出工厂方法来。
以下为firefox developer提供的写法。
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Details_of_the_Object_Model
// Define the Person constructor
function Person(firstName) {
this.firstName = firstName;
}
// Add a couple of methods to Person.prototype
Person.prototype.walk = function(){
alert("I am walking!");
};
Person.prototype.sayHello = function(){
alert("Hello, I'm " + this.firstName);
};
// Define the Student constructor
function Student(firstName, subject) {
// Call the parent constructor, making sure (using Function#call) that "this" is
// set correctly during the call
Person.call(this, firstName);
// Initialize our Student-specific properties
this.subject = subject;
};
// Create a Student.prototype object that inherits from Person.prototype.
// Note: A common error here is to use "new Person()" to create the Student.prototype.
// That's incorrect for several reasons, not least that we don't have anything to
// give Person for the "firstName" argument. The correct place to call Person is
// above, where we call it from Student.
Student.prototype = Object.create(Person.prototype); // See note below
// Set the "constructor" property to refer to Student
Student.prototype.constructor = Student;
// Replace the "sayHello" method
Student.prototype.sayHello = function(){
alert("Hello, I'm " + this.firstName + ". I'm studying " + this.subject + ".");
};
// Add a "sayGoodBye" method
Student.prototype.sayGoodBye = function(){
alert("Goodbye!");
};
// Example usage:
var student1 = new Student("Janet", "Applied Physics");
student1.sayHello(); // "Hello, I'm Janet. I'm studying Applied Physics."
student1.walk(); // "I am walking!"
student1.sayGoodBye(); // "Goodbye!"
// Check that instanceof works correctly
alert(student1 instanceof Person); // true
alert(student1 instanceof Student); // true
Regarding the Student.prototype = Object.create(Person.prototype); line: On older JavaScript engines without Object.create, one can either use a "polyfill" (aka "shim", see the linked article), or one can use a function that achieves the same result, such as:
function createObject(proto) {
function ctor() { }
ctor.prototype = proto;
return new ctor();
}
// Usage:
Student.prototype = createObject(Person.prototype);
不好的实践:扩展原生对象的原型
一个经常使用的不好实践是扩展Object.prototype或者其他内置对象的原型。
该技术被称为monkey patching,它破坏了对象的封装性。虽然一些流行的框架(如Prototype.js)在使用该技术,但是该技术依然不是好的实践,附加的非标准的方法使得内置的类型混乱。
扩展内置对象原型的唯一正当理由是移植较新JavaScript引擎的特性,如Array.forEach。
结论
在编写使用到原型继承模型的复杂代码前理解原型继承模型十分重要。同时,还要清楚代码中原型链的长度,并在必要时结束原型链,以避免可能存在的性能问题。更进一步,除非为了兼容新JavaScript特性,否则永远不要扩展原生对象的原型。