The prototype chain & inheritance of JavaScript in layman's

Source: Internet
Author: User
Tags hasownproperty

The inheritance mechanism of the JavaScript language, which does not have the concept of "subclass" and "parent class", nor the distinction between "class" and "instance" (instance), it relies on a very peculiar "prototype chain" (prototype chain) pattern to implement inheritance.

This part of the knowledge is also one of the core focus of JavaScript, but also a difficult point. I collated the study notes to facilitate learning, but also to deepen their impressions. This part of the code is a lot of detail, need repeated deliberation. So let's get started.

Try your skill.

Prototype chain example (in the comments, you can copy the code into the browser test, the same below)

functionfoo () {} //Defines a function object by using function foo () {} foo.prototype.z= 3; the//function defaults with a prototype object property (typeof foo.prototype;//"Object") varobj =Newfoo (); //We have constructed a new object by way of the new Foo () constructor obj.y= 2; //Add two attributes to obj obj.x by assigning a value= 1; // by constructing the object in this way, the prototype of the object will point to the prototype property of the constructor, i.e. Foo.prototype                              obj.x; //1 //When accessing obj.x, the X attribute is found on obj, so 1 is returned obj.y;//2 //When accessing obj.y, the Y attribute is found on obj, so 2 is returned Obj.z;//3  //When accessing obj.z, I find that there is no Z attribute on obj. It does not stop looking, it looks for its prototype, that is, Foo.prototype, when Z is found, so it returns 3.
//We create the object by literal or the default prototype object of the function, in fact it also has a prototype, its prototype points to Object.prototype, and then Object.prototype is also a prototype, its prototype point NULL
So what does the object.prototype here do?
typeofobj.tostring;//' function '

//We find that typeof obj.tostring is a function, but there is no ToString method on the object or on the object's prototype, because in its prototype chain the There is a Object.prototype method before the end null,
And ToString is the method above Object.prototype. This also explains why JS basically has a ToString method for all objects
inch // true               //Obj.z is inherited from Foo.prototype, so  ' z ' in obj returns True
// false   //But obj.hasownproperty (' Z ') returns false, which means that Z is not on the obj direct object, but is the property above the prototype chain of the object. (Hsaownproperty is also the method on Object.prototype) 

Just now we visited X, Y and Z, respectively, through the prototype chain to find, we can know: when we access a property of an object, and there is no corresponding property on the object, then it will look up through the prototype chain, always find null has no words, will return undefined.

Prototype-based inheritance

function Foo () {   this. y = 2;       = 1; var New Foo ();  //① when using new to invoke, the function is invoked as a constructor   ②this will point to an object (here is Obj3), and the object's prototype will point to the constructor's prototype property (this is Foo.prototype)
// 2
// 1 //You can see that Y is on the object and X is the prototype on the prototype chain (i.e. Foo.prototype)
Prototype properties and Prototypes

Let's see what the structure of Foo.prototype is, and when we use a function declaration to create an empty function, the function has a prototype property, and it defaults to two properties, constructor and __proto__,

The constructor property points to itself foo,__proto__ is exposed in chrome (not a standard attribute, knowing the line), then Foo.prototype's prototype will point to Object.prototype. So Object.prototype on

Some of the methods tostring,valueof will be used by each generic object.

function Foo () {} typeof // "Object" foo.prototype.x = 1; var New Foo ();

To sum up: here we have a Foo function, which has a prototype object property, and its function is to use new Foo () to construct the instance, the prototype property of the constructor will be used as a prototype for the new object.

So we have to figure out that prototype and prototypes are two different things, prototype is a preset property on a Function object, and the prototype is usually the prototype property on the constructor.

Implement a class to inherit another class
functionPerson (name, age) { This. Name =name; Direct call, this point to the global object (this knowledge point collation) This. Age =Age ; //// using new to invoke Peoson, this will point to an empty object with a prototype of Person.prototype, assign a value to an empty object by THIS.name, and finally this is the return value  } Person.prototype.hi=function() {  //Create all the methods shared by the person instance through Person.prototype.hi,(you can refer to the left image of the previous section: the prototype of the object points to the prototype property of the constructor, so you want to obj1,obj2, Obj3 share some methods, you just need to add properties and methods on the prototype object one at a time); Console.log (' Hi, my name is ' + This. Name + ', I am ' + this.age + ' years old now. ')//This is the global object};   Person.prototype.LEGS_NUM = 2; Then set some data shared by all instances of the person class Person.prototype.ARMS_NUM = 2; Person.prototype.walk = function() {console.log (this.name +' Is walking ... ');}; function  Student (name, age, ClassName) {//each student belongs to the person Person.call (this, name, age); In this subclass of student, first call the parent class this.classname = ClassName;}
The next step is how we're going to inherit the student instance Person.prototype some of the ways
Student.prototype = object.create (Person.prototype); Object.create (): Creates an empty object, and the prototype of the object points to its parameters//This way we can look up to the person.prototype when we access the Student.prototype, You can also create your own method without affecting the personStudent.prototype.constructor = Student; Maintain consistency, not set the words constructor will point to personStudent.prototype.hi = function() {///by Student.prototype.hi Such an assignment can override our base class Person.prototype.hi Console.log (' Hi, my name is ' + This. Name + ', I am ' + This. Age + ' years ', and from ' + This. ClassName + '. ');} Student.prototype.learn=function(subject) {//At the same time, we have our own Learn method Console.log ( This. Name + ' is learning ' + subject + ' at ' + This. ClassName + '. ');};//TestvarYun =NewStudent (' Yunyun ', $, ' Class 3,grade 2 '); Yun.hi (); //hi,my name is Yunyun,i ' m of years old Now,and from Class 3, Grade 2.Console.log (Yun. Arms_num);//2//Our own object is not, the prototype of the object is also not student.prototype, but we used the inheritance, continue to look up, found the Person.prototype.ARMS_NUM, so return 2Yun.walk ();//Yunyun is walking ...Yun.learn (' math ');//Yunyun is learning math at Class 3,grade 2.

In conjunction with the diagram, we will analyze the above code: we first created an instance of student with new student Yun,yun's prototype points to the prototype property of the constructor (this is Student.prototype), There are hi methods and learn methods on the Student.prototype, Student.prototype is constructed by Object.create (Person.prototype), So the student.prototype here is an empty object, and the prototype of the object points to Person.prototype, and we also set the Legs_num,arms_num property and hi on the Person.prototype, Walk method. Then we define a person function directly, Person.prototype is a pre-set object, it will have its own prototype, its prototype is Object.prototype, and it is because of this, we have a random object will have hasownproperty,valueof, ToString is a common function, and these functions are all from Object.prototype.       This way, the inheritance based on the prototype chain is implemented. So what happened when we called the Hi,walk,learn method? For example, when we call the Hi method, we first look at the object Yun there is no Hi method, but in this instance does not look up, Finding the Yun prototype, which is Student.protoype, has this hi method, so the final call is Student.prototype.hi, which is similar to calling other methods.

Change prototype

We know that the prototype prototype in JavaScript is not as hard to dynamically change as the class in Java Class,java, but the prototype in JavaScript is actually an ordinary object, That means we can also dynamically add or remove properties to prototype at the stage of the program's operation.

On the basis of the above code, we have Yun This example, and we proceed to experiment:

 student.prototype.x = 101;   The Yun's prototype is dynamically added to a property xyun.x by student.prototype.x;  // 101 //we find that all instances are affected.   //then we'll do an interesting experiment student.prototype  = {Y:2};  We directly modify the prototype property of the constructor and assign it to a new object yun.y;   // undefined  yun.x; // 101   So we come to the conclusion that when we   When you modify the Student.prototype value, you cannot modify an object that has already been instantiated   
var New Student (' Tom ', 3, ' Class LOL kengb ');  
// undefined But when we create a new instance, this time x is gone,
// 2 //And Y is the new value

So when dynamically modifying prototype, it will affect all created or newly created instances, but modifying the entire prototype assignment to a new object will have no effect on the created instance, but will affect subsequent instances.

Ways to implement Inheritance

There are several ways to implement inheritance, and we'll analyze it with person and student.

function Person () {} function  //  can we not use this method? This method is wrong: Because subclass student has its own methods
, if the student is changed by such a sub-assignment, the person is changed as well. New/ /This approach is achievable, but calling constructors can sometimes be problematic, such as passing in person a name and age
, the student here is a class, has not materialized, this time some strange, pass nothing. //Relative This method is ideal, here we create an empty object
, and the object's prototype points to Person.prototype, so that we are guaranteed to inherit the method on Person.prototype, and Student.prototype has its own empty object.
But Object.create was ES5 later.

The prototype chain & inheritance of JavaScript in layman's

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.