首页 > 技术文章 > JavaScript _proto_、prototype原型、原型链、constructor构造器、类式继承、原型继承

reamd 2015-11-15 21:52 原文


1. prototype、_proto_、constructor、原型链

var Person = function(name)  
     {  
         this.name = name ;  
     };  
var p = new Person("reamd");  

console.log('参考下面的图示看效果更佳')
console.log('1 ', Person.__proto__ === Function.prototype);  //true 
console.log('2 ', Object.__proto__ === Function.prototype); // true 
console.log('3 ', Function.__proto__ === Function.prototype); //true  

console.log('4 ' + typeof p.__proto__);    //objcect  
console.log('5 ' + typeof Object.__proto__)//function
console.log('6 ', p.__proto__.__proto__ === Object.prototype); //true 
console.log('7 ', Function.prototype.__proto__ === Object.prototype); //true  
console.log('8 ' + Object.prototype.__proto__); //null  
console.log('9 ', p.__proto__ === Person.prototype)//true

console.log('10 ' + p.constructor)//function(name)
console.log('11 ' + Person.constructor) //Functiion()
console.log('12 ' + Function.constructor)//Functiion()
console.log('13 ' + Object.constructor) //Functiion()

console.log('14 ' + p.__proto__.constructor)//function(name)
console.log('15 ' + Person.prototype.constructor) //function(name)
console.log('16 ' + Function.prototype.constructor) //Function()
console.log('17 ' + Object.prototype.constructor) //Object()

图示,上面的函数可用如下图例表示
prototype和_proto_的关系
知识点:

  1. 任何一个由构造器产生的对象都有_proto_属性,且此属性指向该构造器的prototype。
  2. 所有构造器/函数的_proto_都指向Function的prototype。
  3. Js中一切皆为对象
  4. proto 最终指向的都是Object.prototype
  5. constructor 指向创建当前对象的构造函数
  6. 函数.prototype.construnctor 指向这个函数(或函数A.prototype.construnctor 指向函数A)

*注:
①A.proto 指向 A的构造器.prototype (知识点1)
②A.constructor 指向 A的构造器 (知识点5)
③A.prototype.constructor 指向A (知识点6)
*

总结

  1. A.constructor === A的构造器(A的构造函数)
  2. A._proto_ === A的构造器.prototype
  3. A.prototype === A的原型(原型对象)
  4. _proto_最终的指向都是Object.prototype._proto_为null,由此形成的链叫做原型链

2. 类式继承、原型继承

2-1 类式继承

//Super class  
function Person(){  
    this.sex = 'man';
    this.name='reamd';  
    this.age=23;  

    this.getName = function(){  
        return this.name;  
    };  
};  


Person.prototype.getAge = function(){  
        return this.age;  
};  

//sub class  
function reader(){  
    reader.superclass.constructor.call(this);  
};

//类式继承方法
function extend(sub,sup){  
        var f = function(){};  
        f.prototype = sup.prototype;  
        sub.prototype = new f();  
        sub.prototype.constructor = sub;  
        sub.superclass = sup.prototype;
        if(sup.prototype.constructor !== sup)  
        sup.prototype.constructor = sup;  
}  

extend(reader,Person);
var r = new reader();
console.log(r.getName());
console.log(r.getAge());

2-2 原型继承

var Person = {  
    defaultName : 'zhangshengli',  
    getName : function(){  
    return this.defaultName;  
    }  
};  
var Reader = create(Person);  
alert(Reader.defaultName);
//原型继承核心代码
function create(o) {  
     function F() {};
     F.prototype = o;
     return new F();
}  

下面有两种变体

//第一种变体
 Object.prototype.create= function () {  
    function F() {}  
    F.prototype = this;  
    return new F();  
};  
newObject = oldObject.create();  
//第二种变体
if (typeof Object.create !== 'function') {  
      Object.create = function (o) {  
         function F() {}  
         F.prototype = o;  
         return new F();  
     };  
}  
newObject = Object.create(oldObject);  

推荐阅读