Js深入了解原型对象

  无论什么时候,只要新创建了一个函数,就会自动为这个函数创建一个prototype属性,这个属性指向这个函数的原型对象。

与此同时,这个原型对象也会创建一个constructor属性,这个属性指向prototype属性所在的函数的指针。

举个例子:

就上一篇文章的Person函数来说,Person.prototype就指向它的原型函数,而原型函数Person.prototype.constructor指向Person,大概就是这个意思。

当用构造函数创建一个新实例后,其内部会创建一个指针指向构造函数的原型对象。[[prototype]]

  如何判断一个由构造函数创建的实例的属性[[prototype]]所指向的对象是某个构造函数的原型那?

判断方法如下:

Person.prototype.isPrototypeOf(person1);如果person1实例的[[prototype]]属性指向了Person函数所指向的原型对象,则返回true否则返回false。

  如何获取一个实例的[[prototype]]属性?

方法如下:

Object.getPrototypeOf(person1)==Person.prototype;返回true

Object.getPrototypeOf(person1).name;返回原型中的name属性值。

  每当代码读取某个对象的某个属性时,都会执行一次搜索,搜索顺序是,首先搜索对象实例本身,如果在实例中找到了具有给定名字的属性,则返回改属性值,如果没找到,则去搜索指针所子祥的原型对象。

  如果对象中的属性名称与原型中的属性名称相同,则会屏蔽掉原型中的同名属性。

  要取得对象上,所有可枚举的属性,可使用Object.key()方法,这个方法接收一个对象或者对象的实例作为参数,返回这个对象的可枚举的属性的数组。

  例如:

var keys = Object.key(Person.prototype);//以上一节的Person对象为例,此时数组keys的值为[name,age,job,sayName]。

注意,这里返回的只是所传对象或实例中的属性数组,并不包含对象的原型中的属性。

  如果想取得对象中的所有属性,不管该属性是否可枚举,可以使用Object.getOwnPropertyNames(Person.prototype);//此时返回的数组中,多了一个constructor属性。

  更简单的原型对象创建语法:

function Person()
{}
Person.prototype = {
    name:"aa",
    age:26,
    job:"bb",
    sayName:function(){
        alert(this.name);
    }
}

上边这段代码相当于向Person对象重新定义了一个prototype属性,这个属性的指针指向了一个自定的对象,而并非系统所创建的原型,所以Person.prototype中不再有属性constructor属性。
解决办法是手动在prototype属性中,加入属性constructor:Perosn。或者更严谨一点,在上边的代码的基础上,加入如下代码:

Object.defineProperty(Person.prototype,"constructor",{

  enumerable:false,

  value:Person

});

  使用原型创建对象需要强调一点,不能把Js中的原型完全理解为真正意义上的对象,传统的对象我们在实例化它之后,会在堆中分配一段内存来存放期实例,也就是说我们确实实例化了一个完整的对象,而Js中实例化对象后,实际上是创建了一个指向一个(公共原型+特性对象)的指针,其中的公共原型是所有实例共享且唯一,所以一个实例对原型的修改同事会反映在其他实例上。

 

  

 

posted @ 2013-06-20 00:56  云端天籁  阅读(170)  评论(0)    收藏  举报