读书人

ECMAScript原形模型

发布时间: 2012-11-22 00:16:41 作者: rapoo

ECMAScript原型模型

1.prototype(原型):创建每一个函数都有拥有一个prototype属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。换句话说:prototype就是通过调用构造函数而创建的那个对象实例的原型对象。使用原型的好处在于可以让所有实例共享它所包含的属性和方法(共享原型对象所有属性和方法)。

例子:

function Person(){}//创建空的构造函数var per1=new Person();//创建一个Person实例var per2=new Person();//创建一个Person实例

?2.ECMAScript原型对象

只要创建一个函数,就会根据一组特定的规则为该函数创建一个protoype属性,这个属性指向函数的原型对象。在默认情况下,所有原型对象都会自动获得一个constuctor(构造函数)函数,这个属性包含一个指向prototype属性所在函数的指针。以上例来讲,Person.prototpye.contructor指向Person。通过此构造函数,我们还可以继续添为原型对象添加属性。

在创建自定义构造函数之后,其原型对象默认只会取得constructor属性;至于其他方法则从Object继承而来。当调用构造函数创建一个新的实例后,该实例内部将包含一个指针(内部属性),指向构造函数的原型对象。在很多内部实现中,这个内部属性的名字是_proto_,而且可以访问到(Firefox,Safari、Chrome、Actionscript),而其他的实现这个对象则完全不可见。需要明确一点是:这个连接存在于实例与构造函数的原型对象之间,而不是实例与构造函数之间。

原型对象最初只包含constructor属性,二该属性也是共享属性,一次可以通过对象访问实例。(如下图:最初情况)

ECMAScript原形模型




图中展示了Person构造函数、Person 的原型对象以及Person现有两个实例之间的关系。此时,Person.prototype指向了原型对象,而Person.prototype.constructor又指回了Person。per1和per2都包含一个内部属性该属性仅仅指向了Person.prototype,换句话说它们与构造函数没有直接关系。

function Person(){}//创建空的构造函数//通过prototype添加属性,可以实现为所有实例共享属性和方法Person.prototype.name="张三";//Person函数拥有一个prototype属性Person.prototype.age=29;Person.prototype.job="软件工程师";Person.prototype.sayName=fucntion(){       alert(this.name);};var per1=new Person();//创建一个Person实例per1.sayName();//"张三"var per2=new Person();//创建一个Person实例per2.sayName();//"张三"alert(per1.sayName==per2.sayName)//true,说明调用的是同一个函数
?

下图是添加了额外属性之后关系图:

ECMAScript原形模型

2.可以通过对象实例访问保存在原型中的值,但是不能通过对象实例重写原型中的值。如果在实例对象中添加一个与原型对象中相同名称的属性,那么实例对象取到值将是对实例对象的属性值。

function Person(){}//创建空的构造函数//通过prototype添加属性,可以实现为所有实例共享属性和方法Person.prototype.name="张三";//Person函数拥有一个prototype属性Person.prototype.age=29;Person.prototype.job="软件工程师";Person.prototype.sayName=fucntion(){       alert(this.name);};var per1=new Person();//创建一个Person实例per1.name="李四";//实例对象创建一个与原型相同名称的属性per1.sayName();//"李四"var per2=new Person();//创建一个Person实例per2.sayName();//"张三"alert(per1.sayName==per2.sayName)//true,说明调用的是同一个函数

?说明实例对象的name属性屏蔽了原型对象的name的值。可以使用delete操作符删除实例对象的属性。

function Person(){}//创建空的构造函数//通过prototype添加属性,可以实现为所有实例共享属性和方法Person.prototype.name="张三";//Person函数拥有一个prototype属性Person.prototype.age=29;Person.prototype.job="软件工程师";Person.prototype.sayName=fucntion(){       alert(this.name);};var per1=new Person();//创建一个Person实例per1.name="李四";//实例对象创建一个与原型相同名称的属性per1.sayName();//"李四"delete pre1.name;//删除实例对象的name属性per1.sayName();//"张三"var per2=new Person();//创建一个Person实例per2.sayName();//"张三"alert(per1.sayName==per2.sayName)//true,说明调用的是同一个函数

?

3.从上述代码观察,可以得出以下结论:

每当代码读取某个实例对象的属性时,都会执行一次搜索,目标是具有给定名字的属性(或者方法)。搜索首先从实例对象本身开始,如果发现属性(或者方法)存在,则返回对应的值;如果不存在则会搜索原型对象的属性(或者方法),如果存在则返回值。这也是多个对象实例共享原型对象所保存的属性和方法的基本原理。

4.使用hasOwnProperty()方法可以检测一个属性是存在于实例对象中,还是存在于原型对象中。此方法继承自Object,只在给定属性存在于对象实例中时,才返回true。

function Person(){}//创建空的构造函数//通过prototype添加属性,可以实现为所有实例共享属性和方法Person.prototype.name="张三";//Person函数拥有一个prototype属性Person.prototype.age=29;Person.prototype.job="软件工程师";Person.prototype.sayName=fucntion(){       alert(this.name);};var per1=new Person();//创建一个Person实例per1.name="李四";//实例对象创建一个与原型相同名称的属性per1.sayName();//"李四"alert(per1.hasOwnProperty("name"));//truevar per2=new Person();//创建一个Person实例per2.sayName();//"张三"alert(per2.hasOwnProperty("name"));//falsealert(per1.sayName==per2.sayName)//true,说明调用的是同一个函数
?


读书人网 >Web前端

热点推荐