So you like this --- prototype and prototype chain

  The JS prototype and prototype chain re-sort again, and then hands drew a flow chart, prototype and prototype chain of secret hidden in this picture. Benefit is in the process flow diagrams drawn in, both to test his grasp of the knowledge of the situation, while during the drawing process would be more impressive this knowledge, a more thorough understanding, recommended that each interested guy came personally once.

  In order to move towards a clearer understanding of the prototype chain, create three constructors to build multiple inheritance, respectively Person, ChinaPerson, ProvincePerson, inheritance relationship between them is: ProvincePerson inherited ChinaPerson, ChinaPerson inherits Person. Next, we

  1. First paste this code multiple inheritance;
  2. Flow diagrams, a flowchart of a secret analysis prototype chain;
  3. Write some test code to verify;

  First pasting the code, each sub-constructor on the basis of inheriting the parent's on, respectively, in the constructor function and prototype inside, add your own custom attributes and methods; in addition to write and constructors inside of the same name on the Person prototype property and method, when the same name is used to verify the name of the method, the method of the constructor function and the prototype method which preferentially executed; on ProvincePerson rewritten inherited from the parent method, rough side showing an object-oriented multi-state characteristic.

/ * * 
 * JavaScript multi-level inheritance and polymorphism, reflecting the prototype and prototype chain 
 * * / 
// 1.1 constructor: people (the Person) 
function the Person (name) {
     the this .name = name name:? "Humanity" ;
     the this .methodPerson = function () { 
        the console.log ( "the Person constructor method which methodPerson -> I tags:" + the this .name); 
    } 

    the console.log ( "the Person configured ******** initializes ******** " ); 
} 
// added to the prototype Person attributes and methods 
Person.prototype.age = 18 is ; 
Person.prototype.run = function () { 
    the console.log ("Person prototyping RUN -> name:" + the this .name + ", Age:" + the this .age + ", cheerful RUN" ); 
} 
// problem: If the prototype constructor inside the properties and methods and the properties and methods of the same name the constructor, the implementation of which instance of an object when calling the properties and methods? 
// name name of Person and Person constructor prototype, which calls the object instance? 
Person.prototype.name = "descendants" ; 
Person.prototype.methodPerson = function () { 
    the console.log ( "the Person methodPerson prototype method -> tag:" + the this .name + ", Age:" + the this . Age); 
} 


// 1.2 constructor: Chinese people (ChinaPerson), inherited from the person 
function ChinaPerson (name, Skin) { 
    Person.call ( the this , name);Person constructor calls the parent 

    the this .skin = Skin Skin: "yellow"? ;
     The this .methodChinaPerson = function () { 
        console.log ( "constructor inside ChinaPerson method methodChinaPerson -> color:" + the this .skin + " label: "+ the this .name); 
    } 

    the console.log ( " constructor initializes ChinaPerson ******** ******** " ); 
} 
// set ChinaPerson prototype prototype Person., quite ChinaPerson succession in the Person 
ChinaPerson.prototype = the Object.create (Person.prototype);
 // set new prototype constructor point to themselves 
ChinaPerson.prototype.constructor = ChinaPerson; 

// to ChinaPerson prototype custom add properties and methods
ChinaPerson.prototype.hero = "Tan" ; 
ChinaPerson.prototype.write = function () { 
    the console.log ( ! "ChinaPerson prototype method which write -> I Hengdao days from laughing, hepatobiliary fate is who Kunlun ? "+ the this .hero +", label: "+ the this .name +", Skin: "+ the this .skin); 
} 


// 1.3 constructor: ProvincePerson, inherited from ChinaPerson 
function ProvincePerson (name, Skin, COUNT) { 
    ChinaPerson.call ( the this , name, Skin);   // call the parent class constructor ChinaPerson 

    the this .count = COUNT COUNT: 8000? ;  
     the this .methodProvincePerson = function () { 
        Console.log("ProvincePerson inside the constructor method methodProvincePerson -> Number:" + the this .count + "Wan, color:" + the this .skin + ", Label:" + the this .name); 
    } 
    // override inherited from the parent the method of down methodChinaPerson 
    the this .methodChinaPerson = function () { 
        the console.log ( "ProvincePerson constructor method which override the parent .... methodChinaPerson" ); 
    } 
    the console.log ( "******** configured ProvincePerson initializes ******** " ) 
} 
// set point ChinaPerson ProvincePerson prototype prototype equivalent constructor ProvincePerson inherited ChinaPerson 
ProvincePerson.prototype = the Object.create (ChinaPerson.prototype);
 set point new prototype constructor own// 
ProvincePerson.prototype.constructor = ProvincePerson;
 // to the prototype ProvincePerson custom add properties and methods 
ProvincePerson.prototype.feature = "Changsha tofu" ; 
ProvincePerson.prototype.eat = function () { 
    the console.log ( "ProvincePerson prototype method which eat -> label:" + the this .name + ", local snacks are:" + the this .feature + ", Hero:" + the this .hero + ", Skin:" + the this .skin); 
} 
// override inherited from the parent down prototype method 
ProvincePerson.prototype.write = function () { 
    the console.log ( "write ProvincePerson prototype which override methods inherited from the parent prototype -> .... ^ _ ^ ");
}
View Code

 

  Combination of the above code structure mapping function prototype chain relationship, as shown below:

  

On the map is described, and the prototype chain knowledge points to summarize:

  • ProvincePerson, ChinaPerson, Person three custom constructor, Function, Object two systems is the constructor;
  • Prototype chain direction (direction looking parent) is: ProvincePerson -> ChinaPerson -> Person -> Object -> null; Function -> Object -> null;
  • Figure above obj is an instance of an object constructor ProvincePerson; rectangles represent the constructor, hexagonal prototype object representing the constructor, the red dotted line represents the object instance attribute by its private prototype prototype __proto__ Looking to the parent;
  • is the prototype attribute constructors, __ proto__ is a property of the object instance constructor ;
    • Examples of object points __proto__ property constructor prototype property of the object, i.e., instance object .__ proto__ =  Constructor .prototype  ;  
    • __proto__ implicit prototype, usually not recommended for direct use, usually Object.getPrototypeOf (object) to get a prototype of the object instance;
    • __proto__ is an object instance of an object and the prototype constructor
  • Knock focus on:
    • When the function is called with the new keyword, called constructors, such as var obj = new ProvincePerson (). Then ProvincePerson called constructor is a class template;
    • When the function does not use the new keyword, direct call, is a common function, such as ProvincePerson (), Object (), Function (), etc., so use them to call a normal function;
    • All common functions are the constructor Function instance objects, such as Object, Function as an ordinary function call object instance they are the Function.
    • That is why both the function prototype property, but also __proto__ properties because they have a dual identity:
    • The first double life as they are likely to use the new keyword, then they are constructors, there is the prototype property;
    • The second double life as they do not use the new keyword, direct call, this time they are the constructor Function instance of an object, so this time they have __proto__ property.
    • Function as a special present, special is that the Function.prototype proto__ .__ = Function  , i.e. as a prototype constructor (the prototype) and its common object as a prototype example of a function (the __proto__) point to the same object;
  • Constructor prototype constructor property points constructor instance object constructor is also directed constructor, i.e., instance of an object constructor function .prototype.constructor = .constructor constructor of the constructor = 
  • A constructor inherited from the parent class constructor, the parent will have all the external attributes and parties constructor method, and the properties and methods of the parent prototype include;
  • Child constructor can be rewritten properties and methods inherited; constructor function if a method or property, and methods of the same name on the properties or its prototype, the priority of the constructor function or method call attributes;
  • All objects via constructors or prototype chain, trace the origin, are ancestors of the last Object. I.e. all constructors are Object of indirect child or children. Prototype prototype Object is null, here is the ultimate finale!

 

  Knowledge about these points is that, on the basis of the above code, again some test code to test. First test code on a prototype chain relationships:

//测试一下
var pro1 = Person.prototype, pro2 = ChinaPerson.prototype, pro3 = ProvincePerson.prototype;
//ProvincePerson原型的原型 === ChinaPerson的原型
var pro3_china = Object.getPrototypeOf(pro3);

//ProvincePerson原型的原型的原型 === Person的原型
var pro3_person = Object.getPrototypeOf(pro3_china);

//ProvincePerson原型的原型的原型的原型 === Object的原型
var pro3_object = Object.getPrototypeOf(pro3_person);

//Function和Object作为普通函数时是构造函数Function的实例对象,获取这两个实例对象的原型
var pro_function = Object.getPrototypeOf(Function), pro_object = Object.getPrototypeOf(Object);

console.log("************* 原型链测试 start **********")
console.log("构造函数ProvincePerson继承自ChinaPerson, 构造函数ChinaPerson继承自Person, Person继承自Object")
console.log("Object --> Person --> ChinaPerson --> ProvincePerson")
console.log("Person.原型:", pro1);
console.log("ChinaPerson.原型:", pro2);
console.log("ProvincePerson.原型:", pro3);
console.log("ProvincePerson.原型.原型: ", pro3_china);
console.log("ProvincePerson.原型.原型.原型: ", pro3_person);
console.log("ProvincePerson.原型.原型.原型.原型:", pro3_object);
console.log("ProvincePerson.原型.原型 === ChinaPerson.原型 --> ", pro3_china === pro2);
console.log("ProvincePerson.原型.原型.原型 === Person.原型 --> ", pro3_person === pro1);
console.log("ProvincePerson.原型.原型.原型.原型 === Object.原型 --> ", pro3_object === Object.prototype);
console.log("Function.prototype === Function.__proto__ --> ", Function.prototype === pro_function);
console.log("Object.__proto__ === Function.prototype --> ", pro_object === Function.prototype);
console.log("************ 测试 end ************\n")

/*
测试结果:

************* 原型链测试 start **********
构造函数ProvincePerson继承自ChinaPerson, 构造函数ChinaPerson继承自Person, Person继承自Object
Object --> Person --> ChinaPerson --> ProvincePerson
Person.原型: {age: 18, run: ƒ, name: "炎黄子孙", methodPerson: ƒ, constructor: ƒ}
ChinaPerson.原型: Person {constructor: ƒ, hero: "谭嗣同", write: ƒ}
ProvincePerson.原型: ChinaPerson {constructor: ƒ, feature: "长沙臭豆腐", eat: ƒ, write: ƒ}
ProvincePerson.原型.原型:  Person {constructor: ƒ, hero: "谭嗣同", write: ƒ}
ProvincePerson.原型.原型.原型:  {age: 18, run: ƒ, name: "炎黄子孙", methodPerson: ƒ, constructor: ƒ}
ProvincePerson.原型.原型.原型.原型: {constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}
ProvincePerson.原型.原型 === ChinaPerson.原型 -->  true
ProvincePerson.原型.原型.原型 === Person.原型 -->  true
ProvincePerson.原型.原型.原型.原型 === Object.原型 -->  true
Function.prototype === Function.__proto__ -->  true
Object.__proto__ === Function.prototype -->  true
************ 测试 end ************
*/
View Code

   测试结果截图:

 

  再来一份对于多级继承和重写展示的测试代码:

//第二波测试,测试构造函数的继承 和 多态(重写从父级继承下来的属性或方法)
console.log("\n************* 继承和重写 start ************");
console.log(">>>>>>准备创建一个Person实例对象>>>>>");
var per = new Person("王大锤");  
per.methodPerson();
per.run();
console.log("*****Person实例对象测试结论:构造函数和原型有同名属性或方法,实例对象优先调用构造函数的属性或方法*****\n");

console.log("\n>>>>>准备创建一个ChinaPerson实例对象,ChinaPerson继承了Person >>>>>");
var chObj = new ChinaPerson("中国人", "黄色");
chObj.methodChinaPerson();
chObj.write();
chObj.methodPerson();
chObj.run();
console.log("*****ChinaPerson实例对象测试结论:继承自父类Person, 拥有父类所有对外的构造函数里面和原型里面的属性和方法\n");

console.log("\n>>>>>准备创建一个ProvincePerson实例对象,ProvincePerson继承了ChinaPerson>>>>>");
var proObj = new ProvincePerson("湖南人", "黄色", 888);
proObj.methodProvincePerson();
proObj.eat();
proObj.methodChinaPerson();
proObj.write();
proObj.methodPerson();
proObj.run();
console.log("*****ProvincePerson实例对象测试结论:拥有父级和父级的父级的所有对外的,包括构造函数里面和原型里面的属性和方法;另外也可以对父级属性或方法进行重写");
console.log("************  测试 end ************\n");

/*
测试结果打印日志:

************* 继承和重写 start ************
>>>>>>准备创建一个Person实例对象>>>>>
********Person 构造函数 初始化********
Person构造函数里面的方法methodPerson-->我的标签:王大锤
Person原型方法run-->name: 王大锤, age: 18, 欢快的run
*****Person实例对象测试结论:构造函数和原型有同名属性或方法,实例对象优先调用构造函数的属性或方法*****

>>>>>准备创建一个ChinaPerson实例对象,ChinaPerson继承了Person >>>>>
********Person 构造函数 初始化********
********ChinaPerson 构造函数 初始化********
ChinaPerson构造函数里面的方法methodChinaPerson-->肤色:黄色, 标签: 中国人
ChinaPerson原型里面的方法write-->我自横刀向天笑,去留肝胆两昆仑!is who? 谭嗣同, 标签: 中国人, skin: 黄色
Person构造函数里面的方法methodPerson-->我的标签:中国人
Person原型方法run-->name: 中国人, age: 18, 欢快的run
*****ChinaPerson实例对象测试结论:继承自父类Person, 拥有父类所有对外的构造函数里面和原型里面的属性和方法

>>>>>准备创建一个ProvincePerson实例对象,ProvincePerson继承了ChinaPerson>>>>>
********Person 构造函数 初始化********
********ChinaPerson 构造函数 初始化********
********ProvincePerson 构造函数 初始化********
ProvincePerson构造函数里面的方法methodProvincePerson-->数量:888万, 肤色:黄色, 标签:湖南人
ProvincePerson原型里面的方法eat-->标签:湖南人, 地方小吃是:长沙臭豆腐, hero: 谭嗣同, skin: 黄色
ProvincePerson构造函数里面重写父级方法methodChinaPerson....
ProvincePerson原型里面重写从父级原型继承的write方法-->。。。。^_^
Person构造函数里面的方法methodPerson-->我的标签:湖南人
Person原型方法run-->name: 湖南人, age: 18, 欢快的run
*****ProvincePerson实例对象测试结论:拥有父级和父级的父级的所有对外的,包括构造函数里面和原型里面的属性和方法;另外也可以对父级属性或方法进行重写
************  测试 end ************
*/
View Code

 

Guess you like

Origin www.cnblogs.com/tandaxia/p/10966885.html