天天看点

javascript之原型

原型

每个函数都有一个prototype属性,它是一个对象,也称作原型对象,可以将方法和属性写在它上面,而通过这个函数创建出来的实例对象,都能共享这个原型对象下的方法和属性。只需要将想要共享的东西放在该函数的prototype下,不想共享的东西通过构造函数创建
function CretePerson(name){
        this.name=name;    
    }
    CreatePerson.prototype.showName=function(){
        alert(this.name);
    }
    var p1=new CretaePerson('hah');
    p1.showName();
    var p2=new CretaePerson('hehe');
    p2.showName();
    alert(p1.showName==p2.showName);//true,可见showName()方法共享,共用一个内存,当更改了p1的showName也会影响p2的showName
           

proto属性

每个实例化对象都有proto属性,它是一个指针,指向函数的prototype,也就是保存了它的地址(JS中任何对象的值都是保存在堆内存中,我们声明的变量只是一个指针,保存了这个对象的实际地址,所以有了地址就能找到对象)

proto属性保存了构造函数的原型对象的地址,通过这个属性就可以拥有原型对象下的所有属性和方法,proto属性实际就是实例化对象和原型对象之间的连接

原型链

每个函数都可以成为构造函数,每个函数都有原型对象,每个原型对象也可以是一个实例化对象

例如:创建了一个函数fun,它是构造函数function的实例化对象,而function的原型对象,又是Object的实例对象。所以fun有个proto属性可以访问到function的原型对象,function原型对象也是个实例对象,也有个proto属性,可以访问到Object的原型对象,所以通过proto属性就形成了一条原型链。

每个实例化对象都可以访问到链子上方的方法和属性,所以fun是可以访问Object原型对象下的方法和属性的,实际上所有对象都可以访问Object的原型对象。

访问规则:先在自身的下面寻找,再去一级一级的往原型链上找

function Aaa(){}
    Aaa.prototype.num=;
    var a1=new Aaa();
    a1.num=;
    alert(a1.num);//10
           

原型对象

原型对象下三种属性:

1、原型对象所带方法和属性

2、constructor构造函数属性 :每个函数的原型对象都有的默认属性,指向函数。每个实例化对象本身是没有constructor属性的,他们下面默认只有一个proto属性,用来连接原型对象,而和构造函数本身是没有直接联系的,所以它的constructor是访问在原型对象上的,当原型对象的constructor变化了,实例化的constructor也会改变。如果这个对象本身既是原型对象又是实例化对象,就拥有constructor属性,无需从原型对象上访问

3、proto属性

function CreatePerson(name){
        this.name=name;
    }
    CreatePerson.prototype.showName=function(){
        console.log(this.name); 
    };
    var p1=new CreatePerson('haha');
    p1.showName();
    console.log(p1.constructor);//来自CreatePerson.prototype
    console.log(CreatePerson.prototype);//{showName:{},constructor:CreatePerson,_proto_:Object.prototype}
    //可见原型对象保存了:、自身添加的方法,、构造函数constructor,、_proto_(和上一层构造函数原型对象的连接)
    console.log(CreatePerson.prototype.__proto__===Object.prototype);//true 这个原型对象本身又是Object的实例化对象,所有_proto_指向Object的原型对象
    console.log(CreatePerson.prototype.__proto__===Object);// false 可见是和构造函数下原型对象的连接,不是构造函数
    console.log(CreatePerson.prototype.constructor);//CreatePerson CreatePerson.prototype是Object实例化对象,也是原型对象,所以自身拥有constructor属性
    console.log(Object.prototype.__proto__); // null 原型链的终点是null
    console.log(CreatePerson.__proto__); //function.prototype CreatePerson本身既是构造函数又是function的实例化对象,拥有_proto_属性,指向function的原型对象
    console.log(CreatePerson.constructor); // function 继承自function.prototype
    console.log(CreatePerson.prototype instanceof CreatePerson)//验证是否在一条原型链上 false
           

原文:http://www.jianshu.com/p/845ad9b78201