In the traditional Class-based languages such as Java, C ++, the inherited nature is an extension of an existing Class, and generate a new Subclass.
Because this kind of language and the strict zone classification instance, is actually a type of inherited extension. However, JavaScript thanks prototypal inheritance, we can not be extended directly to a Class, Class simply because this type does not exist.
But the approach is still there. We first review the Student
constructor:
function Student(props) { this.name = props.name || 'Unnamed'; } Student.prototype.hello = function () { alert('Hello, ' + this.name + '!'); }
Now we want based on Student
extended out PrimaryStudent
, you can define PrimaryStudent
:
function PrimaryStudent (The props) { // call the constructor Student bind this variable: Student.call ( this , The props); this .grade = || props.grade. 1 ; }
However, calling the Student
constructor does not mean inherited Student
, PrimaryStudent
the prototype object is created:
new PrimaryStudent() ----> PrimaryStudent.prototype ----> Object.prototype ----> null
We must find a way to prototype chain amended as follows:
new PrimaryStudent() ----> PrimaryStudent.prototype ----> Student.prototype ----> Object.prototype ----> null
In this way, the prototype chain of the inheritance relationship on the right. New based PrimaryStudent
not only call the objects created PrimaryStudent.prototype
defined method, you can also call the Student.prototype
methods defined.
If you want to use the most simple and crude way to do it :
PrimaryStudent.prototype = Student.prototype;
It is not enough! If this is the case, PrimaryStudent
and Student
shared a prototype object, that also define PrimaryStudent
doing? (Just like his father a son, he is to maintain the characteristics of his body, can help his father work, but give birth to a son designated shop and go live, let him do to help my father, and that the son born doing ... )
We must use an intermediate target to achieve the correct prototype chain, the prototype object to this middle point Student.prototype
. To achieve this, the reference channel Ye (JSON invention is that Douglas) code, a middle empty function object can F
be achieved:
// PrimaryStudent Constructor: function PrimaryStudent (The props) { Student.call ( the this , The props); the this .grade = || props.grade. 1 ; } // null function F: function F () { } // put the F prototype point Student.prototype: F.prototype = Student.prototype; // to point to a new prototype of PrimaryStudent objects F, F prototype object points exactly Student.prototype: PrimaryStudent.prototype = new new F (); // put PrimaryStudent prototype constructor to repair PrimaryStudent: PrimaryStudent.prototype.constructor = PrimaryStudent; // continue PrimaryStudent prototype (that is, new F () object) define methods: = PrimaryStudent.prototype.getGrade function () { return the this .grade; }; // Create Xiaoming: var Xiaoming = new new PrimaryStudent ({ name: 'Bob' , Grade: 2 }); xiaoming.name; // 'Bob' xiaoming.grade; // 2 // validate prototype: xiaoming .__ proto__ === PrimaryStudent.prototype; // to true xiaoming .__ proto __.__ proto__ === Student.prototype; // to true // verify inheritance: xiaoming instanceof PrimaryStudent; // true xiaoming instanceof Student; // true
Found that such steps inherited a bit cumbersome, it can be packaged up ! ! !
If this action with a succession inherits()
function package together, you can also hide F
the definition and simplify the code:
function inherits(Child, Parent) { var F = function () {}; F.prototype = Parent.prototype; Child.prototype = new F(); Child.prototype.constructor = Child; }
This inherits()
function can be reused:
function Student (The props) { the this .name = props.name || 'break Unnamed' ; } Student.prototype.hello = function () { Alert ( 'the Hello,' + the this .name + '!' ); } function PrimaryStudent ( the props) { Student.call ( the this , the props); the this .grade = || props.grade. 1 ; } // prototyping inheritance chain: inherits (PrimaryStudent, Student); // bind to other methods PrimaryStudent prototype: PrimaryStudent. = prototype.getGrade function () { return the this.grade; };
summary
JavaScript is a prototype implementation inheritance:
-
Define a new constructor and used internally
call()
calls hope "inheritance" of the constructor, and bindthis
; -
By means of an intermediate function
F
prototyping inheritance chain, preferably by encapsulationinherits
completion function; -
Continue to define a new method on the new prototype constructor.