Simple and rude understanding of the JavaScript prototype chain

Source: Internet
Author: User

Nima! That's enough for you too! Don ' t bb! Show me the code!

function person (name) {this.name = name;} function mother () {}mother.prototype = {//mother's prototype age:18, home: [' Beijing ', ' Shanghai ']}; Person.prototype = new mother (); The person's prototype is mother//with the Chrome Debugging tool, which provides a __proto__ interface to view the prototype var p1 = new Person (' Jack '); P1: ' Jack '; __proto__:18,[' Beijing ', ' shanghai ']var p2 = new Person (' Mark '); P2: ' Mark ';  __proto__:18,[' Beijing ', ' shanghai ']p1.age = 20; /* Instances cannot change the base value properties of the prototype, as you do with your mother's hair and hair. * Adding an Age property to the P1 instance is a normal operation, regardless of the prototype. with Var o={}; Like o.age=20. * P1: The following is an attribute of age, and __proto__, like Mother.prototype, age=18. * P2: Only attributes name,__proto__ as Mother.prototype */p1.home[0] = ' Shenzhen '; /* Share of the reference type attribute in the prototype, just as you burned your home and burned your family's home. * This is the first, the following carefully nagging about it? * P1: ' Jack ', 20;    __proto__:18,[' Shenzhen ', ' Shanghai '] * p2: ' Mark '; __proto__:18,[' Shenzhen ', ' Shanghai '] */p1.home = [' Hangzhou ', ' Guangzhou ']; /* In fact, the same operation as P1.age=20. Change to this understanding: Var o={}; o.home=[' big ', ' house '] * P1: ' Jack ', 20,[' Hangzhou ', ' Guangzhou '];                             __proto__:18,[' Shenzhen ', ' Shanghai '] * p2: ' Mark '; __proto__:18,[' Shenzhen ', ' Shanghai '] */delete p1.age; /* Once the properties of the instance are deleted, the original overridden values will be seen. As you shave your bald head, the charming little hair of heredity grows out. * This is the upward search mechanism, first search you, then your mother, then your mother's mother, so your mother's changes will affect you dynamically. * P1: ' Jack ', [' Hangzhou ', ' Guangzhou '];                          __proto__:18,[' Shenzhen ', ' Shanghai '] * p2: ' Mark '; __proto__:18,[' Shenzhen ', ' Shanghai '] */person.prototype.lastname = ' Jin '; /* Rewrite the prototype and react dynamically to the instance. Just as your mother is trendy, the neighbors say you're the son of a hot woman. * Notice, here we rewrite the person's prototype, is to add a lastName attribute to mother, equivalent to mother.lastname= ' Jin ' * Here is not to change mother.prototype, change the different levels, the effect will often have a great difference. * P1: ' Jack ', [' Hangzhou ', ' Guangzhou '];                          __proto__: ' Jin '; __proto__:18,[' Shenzhen ', ' Shanghai '] * p2: ' Mark '; __proto__: ' Jin '; __proto__:18,[' Shenzhen ', ' Shanghai '] */person.prototype = {age:28, address: {country: ' USA ', CI Ty: ' Washington '}};var p3 = new Person (' Obama '); /* Rewrite the prototype! This time the person's prototype has completely become a new object, that is, man changed a mother, called stepmother. * Change to this understanding: Var a=10; B=a; a=20; C=a. So B does not change, become C, so P3 with stepmother change, and the mother has nothing to do. * P1: ' Jack ', [' Hangzhou ', ' Guangzhou ']; __proto__: ' Jin '; __proto__:18,[' Shenzhen ', ' Shanghai '] *P2: ' Mark '; __proto__: ' Jin '; __proto__:18,[' Shenzhen ', ' Shanghai '] * P3: ' Obama '; __proto__: {country: ' USA ', City: ' Washington '} * /mother.prototype.no = 9527;/* rewrites prototypes, dynamically reacting to instances. Just like your mom's a damn fad, the neighbors mention you say your grandmother is a real wave. * Note, here we rewrite is mother.prototype,p1p2 will change, but the above P3 with the mother has no involvement, do not affect him. * P1: ' Jack ', [' Hangzhou ', ' Guangzhou '];                          __proto__: ' Jin '; __proto__:18,[' Shenzhen ', ' Shanghai '],9527 * p2: ' Mark '; __proto__: ' Jin '; __proto__:18,[' Shenzhen ', ' Shanghai '],9527 * P3: ' Obama '; __proto__: {country: ' USA ', City: ' Washington '} */mother.prototype = {car:2, hobby: [' run ', ' walk ']};var P4 = new Person (' Tony '); */* rewrite prototype prototypes! This time mother's prototype has completely become a new object! Man, he's got a damn stepmother! * As the above person and mother have been disconnected, this time mother how to change has not affected person. * P4: ' Tony '; __proto__: {country: ' USA ', City: ' Washington '} */person.prototype = new mother (); Bind var P5 again = new person (' Luffy ');//This time if you need to apply these changes, it is necessary to re-bind the person's prototype to the mother//P5: ' Luffy '; __proto__: 2, [' Run ', ' Walk ']p1.__proto__.__proto__.__proto__.__proto__//nUll, did you say that the end point of the prototype chain is not NULL? Mother.__proto__.__proto__.__proto__//null, you say the end of the prototype chain is not NULL?

Have you read the basics?

Now say P1.age = 20, p1.home = [' Hangzhou ', ' Guangzhou '] and p1.home[0] = ' Shenzhen ' difference.  P1.home[0] = ' Shenzhen '; A summary of this is the form of p1.object.method,p1.object.property.

P1.age = 20; P1.home = [' Hangzhou ', ' Guangzhou ']; These two sentences are better understood, forget the prototypes first, and think about how we add properties to an ordinary object:

var obj = new Object (); obj.name= ' xxx '; Obj.num = [100, 200];

Does that make sense? The same thing.

Then why p1.home[0] = ' Shenzhen ' will not create a home array property under P1 and then set its first to ' Shenzhen '? Let's just forget this, think of the Obj object above, if it's written like this: var obj.name = ' xxx ', obj.num = [100, 200], can you get the result you want? Obviously, you can't get anything but an error. Because obj is not yet defined, how can you add something to it? Similarly, the home in p1.home[0] is not defined under P1, so it is not possible to define home[0 directly in a single step. If you want to create a home array under P1, of course this is the case:

P1.home = []; P1.home[0] = ' Shenzhen ';

Isn't that the way we use it the most?

And the reason p1.home[0] = ' Shenzhen ' does not directly error, because there is a search mechanism in the prototype chain. When we enter the P1.object, the search mechanism of the prototype chain is to search for the corresponding value in the instance first, find it in the prototype, and then search for the top-level prototype. All the way to the end of the prototype chain is to return a undefined if the null has not been found. When we enter P1.home[0], is also the same search mechanism, first search P1 see there is a property called home and methods, and then step up to find. Finally we found it in the prototype of mother, so modifying him would be equivalent to modifying the mother prototype.

In a nutshell: p1.home[0] = ' Shenzhen ' equals mother.prototype.home[0] = ' Shenzhen '.

As can be known from the above analysis, the main problem of the prototype chain inheritance is the sharing of attributes, many times we just want to share the method and do not want to share the property, ideally each instance should have a separate attribute. As a result, there are two ways to improve the prototype inheritance:

1) Combination Inheritance
function Mother (age) {    this.age = age;    This.hobby = [' Running ', ' football ']}mother.prototype.showage = function () {    console.log (this.age);};  function person (name, age) {     Mother.call (this, age); Second execution    this.name = name;}  Person.prototype = new mother (); First time execution Person.prototype.constructor = person; Person.prototype.showName = function () {    console.log (this.name);} var p1 = new Person (' Jack ', 20); P1.hobby.push (' basketball ');  P1: ' Jack '; __proto__:20,[' running ', ' football ']var p2 = new Person (' Mark ', +);  P2: ' Mark '; __proto__:18,[' running ', ' football ']

The result is Jiangzi:

The first time this is performed, get Person.prototype.age = undefined, Person.prototype.hobby = [' Running ', ' Football '], the second execution is var p1 = new Per Son (' Jack ', 20), got P1.age =20, p1.hobby = [' Running ', ' Football '],push after it became p1.hobby = [' Running ', ' Football ', ' Basketb All ']. In fact, it is easier to understand this change, and this can be achieved by simply replacing it. If the feeling is more around, try to throw away the concept inside the mind, and put yourself in the browser from top to bottom to execute the code, the result is not out?

By the second execution of the prototype's constructor, mother (), we copy the properties of a prototype in the object instance so that it is separate from the prototype attribute. Careful you will find that the first time we call Mother (), as if nothing to do, can not call him? Yes, we have the following parasitic combined inheritance.

2) Parasitic combined inheritance
function Object (o) {    function F () {}    f.prototype = O;    return new F (); function Inheritprototype (person, mother) {    var prototype = object (Mother.prototype);     Prototype.constructor = person;        Person.prototype = prototype;    } function Mother (age) {    this.age = age;    This.hobby = [' Running ', ' football ']}mother.prototype.showage = function () {    console.log (this.age);}; function person (name, age) {     Mother.call (this, age);    THIS.name = name; }inheritprototype (person, mother); Person.prototype.showName = function () {    console.log (this.name);} var p1 = new Person (' Jack ', 20); P1.hobby.push (' basketball ');//P1: ' Jack '; __proto__:20,[' running ', ' football ']var p2 = new Person (' Mark ', 18); P2: ' Mark '; __proto__:18,[' running ', ' football ']

The result is Jiangzi:

There are no more age and hobby attributes in the prototype, only two methods, which is exactly what we want!

The key is in Object (O), where a temporary object is borrowed to subtly avoid calling new mother (), and then returning the prototype to an O object instance, thus completing the prototype chain setup. Very round, right, that is because we can not directly set Person.prototype = Mother.prototype AH.

Summary

Having said so much, there is only one core: attribute sharing and independent control, when your object instances require independent attributes, all of which are created in object instances. If you don't think too much, you can directly define the attributes you need to be independent in person to overwrite the properties of the prototype. In summary, when using the prototype inheritance, you should pay special attention to the properties in the prototype, because they are reaching.

Below a simple list of the next JS in the creation of the object of the various methods, now the most common method is the combination mode, the familiar classmate can skip to the end of the article likes.

1) Original mode
1. Original mode, object literal way var person = {     name: ' Jack ',    age:18,    sayname:function () {alert (this.name);}};/ /1. Primitive mode, object constructor way var person = new Object ();p erson.name = ' Jack ';p erson.age = 18;person.sayname = function () {    Aler T (this.name);};

Obviously, when we want to create lots of person1, person2 ... , every time to knock a lot of code, Senior Copypaster are unbearable! Then there is the factory model of mass production.

2) Factory mode
2. Factory mode, define a function to create object function Creatperson (name, age) {    var temp = new Object ();     Person.name = name;    Person.age = age;    Person.sayname = function () {        alert (this.name);    };    return temp; }

Factory mode is batch production, simple call can enter the creation of human mode (PA pa ... )。 Specify the name age can build a bunch of babies, free hands. But because it is factory-rigged, so you can not identify the object exactly what type, is a person or a dog silly (instanceof test for object), in addition to each time you create a separate temp object, code bloated, ya minute fly butterfly ah.

3) constructor function
3. Constructor mode, defining a constructor for an object function person (name, age) {    this.name = name;    This.age = age;    This.sayname = function () {        alert (this.name);    };    } var p1 = new Person (' Jack ', 18); Create a P1 object person (' Jack ',);    The property methods are given to the Window object, window.name= ' Jack ', and Window.sayname () will output Jack

Constructors are similar to the constructors of classes in C + +, Java, and are easy to understand, and the person can be identified as type (instanceof test for person, Object). But all instances are still independent, and the methods of the different instances are actually different functions. Here to forget the function two words, the sayname as an object to understand, that is to say Zhang San Sayname and John Doe Sayname is different existence, but obviously we expect to share a sayname to save memory.

4) Prototype mode
4. Prototype mode, directly define the prototype attribute function person () {}person.prototype.name = ' Jack '; Person.prototype.age = 18; Person.prototype.sayName = function () {alert (this.name);};//4. prototype mode, literal definition way function person () {}person.prototype = {
   name: ' Jack ',    age:18,    sayname:function () {alert (this.name);}}; var p1 = new Person (); Name= ' Jack ' var p2 = new Person (); Name= ' Jack '

It is important to note that there is a sharing of prototype properties and methods, that is, all instances only refer to the attribute methods in the prototype, and any changes that occur in any one place can cause changes to other instances.

5) Mixed Mode (construction + prototype)
5. Prototype construction combination mode, function person (name, age) {    this.name = name;    This.age = age;} Person.prototype = {    hobby: [' Running ', ' Football '];    Sayname:function () {alert (this.name);},    sayage:function () {alert (this.age);}}; var p1 = new Person (' Jack ', 20); P1: ' Jack ', 20; __proto__: [' Running ', ' football '],sayname,sayagevar p2 = new Person (' Mark ', 18); P1: ' Mark ', 18;__proto__: [' Running ', ' Football '],sayname,sayage

The practice is to put a separate attribute method into the constructor, while the part that can be shared is put into the prototype, which minimizes memory and preserves the independence of the object instance.

Next article – Closures, goodbye.

Simple and rude understanding of the JavaScript prototype chain

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.