本篇文章主要讲JavaScript对象中的原型模式:
1、理解原型对象
无论什么时候,只要创建了一个新函数,就会根据一组特定的规则为该函数创建一个prototype属性,这个属性指向函数的原型对象。在默认情况下,所有原型对象都会自动获得一个constructor(构造函数)属性,这个属性包含一个指向prototype属性所在函数的指针。
创建了自定义的构造函数之后,其原型对象默认只会取得constructor属性,至于其他方法,则都是从object继承而来的。当调用构造函数创建一个新实例后,该实例的内部将包含一个指针(内部属性),指向构造函数的源性对象。ECMA-262第5版中管这个指针叫[[prototype]]。虽然在脚本中没有标准的方式访问[[prototype]],但FireFox、Safari和chrome在每个对象上都支持一个属性:proto;而在其他实现中,这个属性对脚本则是完全不可见的。不过,要明确的真正重要的一点就是,这个连接存在于实例与构造函数的原型对象之间,而不是存在于实例与构造函数之间。
如下一段代码:
function Person(){
}
Person.prototype.name="Jessica";
Person.prototype.age=25;
Person.prototype.job="Web software Engineer";
Person.prototype.sayName=function(){
alert(this.name);
}
var person1=new Person();
person1.sayName(); //"Jessiva"
var person2=new Person();
person2.sayName(); //"Jessiva"
alert(person1.sayName==person2.sayName); //true
下图展示了这段代码的各个对象之间关系:
虽然在所有的实现中都无法访问到[[prototype]],但可以通过isPrototypeOf()方法来确定对象之间是否存在这种关系。从本质上讲,如果[[prototype]]指向调用isPrototypeOf()方法的对象(Person.prototype),那么这个方法就返回true,如下所示:
alert(Person.prototype.isPrototypeOf(person1)); //true
alert(Person.prototype.isPrototypeOf(person2)); //true
在ECMAScript5增加了一个新方法,叫object.getPrototypeOf(),在所有支持的实现中,这个方法返回[[prototype]]的值。例如:
alert(Object.getPrototypeOf(person1)==Person.prototype); //true
alert(Object.getPrototypeOf(person1).name); //"Jessica"
使用Object.getPrototypeOf()可以方便的取得一个对象的原型,而这在利用原型实现继承(稍后会有文章更新)的情况下是非常重要的。
虽然可以通过对象实例访问保存在原型中的值,但却不恩能够通过对象实例重写原型中的值,如果我们再实例中添加了一个属性,而该属性与实例原型中的一个属性同名,那我们就在实例中创建该属性,该属性将会屏蔽原型中的那个属性。来看下面的例子:
function Person(){
}
Person.prototype.name="Jessica";
Person.prototype.age=25;
Person.prototype.job="Web software Engineer";
Person.prototype.sayName=function(){
alert(this.name);
}
var person1=new Person();
var person2=new Person();
person1.name="Greg";
alert(person1.name); //"Greg"--来自实例
alert(person2.name); //"Jessica"--来自原型
使用delete操作符则可以完全删除实例属性,从而让我们能够重新访问原型中的属性。
使用hasOwnProperty()方法则可以检测一个属性是存在于实例中还是存在于原型中。这个方法(继承于Object)只在给定属性存在于对象实例中,才会返回true。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。