关于js原型及原型链的见解

js是一个动态语言,它不是在编译期间寻找属性值,而是在执行期间寻找属性值.


A的原型继承自B的原型,a对象是由A的原型派生出的对象.如果对象a上的一个属性被请求,则js表现出如下搜索过程:
 
       a.js首先检查a对象上是否存在此属性,如果没有搜索到,则进行第b部分搜索过程。
 
       b.js访问A的原型检查是否有此属性,如果仍然没搜到,则进行第c部分搜索过程。
 
       c. js最后访问B的原型检查是否有此属性.

如果没有搜到将访问每个对象上的原型直到达到根原型上。这样的一个搜索过程称原型链


为什么会用到原型呢?

调用构造函数创建对象时,都会在内存中重新创建一遍构造函数中添加的属性和方法,

而用原型则可以把共享的属性.方法保存在原型对象中,从而让每个实例对象都继承这些属性.方法


不用原型:

function Student(name,age,address){    
    this.name=name;   
    this.age=age;   
    this.address=address;   
    this.sayName=function(){   
         return this.name;   
    };   
    this.sayAddress=function(){   
         return this.address;   
    };   
}   
var student1=new Student(“carney”,“19″,“guangdong”),                   
    student2=new Student(“blank”,“19″,“guangdong”);   
    console.log(student1.sayName()); //carney   
    console.log(student2.sayName());//blank  


用原型:

function Student(name,age,address){    
    this.name=name;   
    this.age=age;   
    this.address=address;   
    }   
Student.prototype.sayName=function(){   
                              return this.name;   
                };   
Student.prototype.sayAddress=function(){   
                             return this.address;   
               };   
Student.prototype.grade=“eight”;   
var student1=new Student(“carney”,“19″,“guangdong”),   
    student2=new Student(“blank”,“19″,“guangdong”);   
    console.log(student1.sayName()); //carney   
    console.log(student2.sayName());//blank  


我们可以通过isPrototypeOf()方法来检验实例和原型对象之间是否存在这种关系,如果实例的[prototype]属性指向调用isPrototypeOf()方法的对 象,那么这个方法就会返回true.

console.log(Student.prototype.isPrototypeOf(student1)); //true   
console.log(Student.prototype.isPrototypeOf(student2)); //true  


另外我们可以使用Object.getPrototypeOf()方法,让它返回实例所指向的原型对象


使用hasOwnProperty()方法可以检测一个属性存在于实例中还是存在于原型中.如果存在于实例中就会返回true,如:

console.log(student1.hasOwnProperty(“name”)); //true   
console.log(student1.hasOwnProperty(“grade”)); //false  


  Function、Object:Js自带的函数对象。

        prototype,每一个函数对象都有一个显示的prototype属性,它代表了对象的原型(Function.prototype函数对象是个例外,没有prototype属性)。

        __proto__:每个对象都有一个名为__proto__的内部隐藏属性,指向于它所对应的原型对象(chrome、firefox中名称为__proto__,并且可以被访问到)。原型链正是基于__proto__才得以形成(note:不是基于函数对象的属性prototype)。



8164530.png


 堆区图说明:
 
        Function.prototype函数对象图内部表示prototype属性的红色虚框,只是为了说明这个属性不存在。


        通过上图Function、Object、Prototype关系图中,可以得出一下几点:

  1. 所有对象所有对象,包括函数对象的原型链最终都指向了Object.prototype,而Object.prototype.__proto__===null,原型链至此结束。

  2. Animal.prototype是一个普通对象。

  3. Object是一个函数对象,也是Function构造的,Object.prototype是一个普通对象。

  4. Object.prototype.__type__指向null。

  5. Function.prototype是一个函数对象,前面说函数对象都有一个显示的prototype属性,但是Function.prototype却没有prototype属性,即Function.prototype.prototype===undefined,所有Function.prototype函数对象是一个特例,没有prototype属性。

  6. Object虽是Function构造的一个函数对象,但是Object.prototype没有指向Function.prototype,即Object.prototype!==Function.prototype。




你可能感兴趣的:(js,原型,原型链)