本篇文章主要讲JavaScript对象中的原型模式:chrome
不管何时,只要建立了一个新函数,就会根据一组特定的规则为该函数建立一个prototype属性,这个属性指向函数的原型对象。在默认状况下,全部原型对象都会自动得到一个constructor(构造函数)属性,这个属性包含一个指向prototype属性所在函数的指针。
建立了自定义的构造函数以后,其原型对象默认只会取得constructor属性,至于其余方法,则都是从object继承而来的。当调用构造函数建立一个新实例后,该实例的内部将包含一个指针(内部属性),指向构造函数的源性对象。ECMA-262第5版中管这个指针叫[[prototype]]。虽然在脚本中没有标准的方式访问[[prototype]],但FireFox、Safari和chrome在每一个对象上都支持一个属性:proto;而在其余实现中,这个属性对脚本则是彻底不可见的。不过,要明确的真正重要的一点就是,这个链接存在于实例与构造函数的原型对象之间,而不是存在于实例与构造函数之间。函数
以下一段代码:this
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
下图展现了这段代码的各个对象之间关系:spa
虽然在全部的实现中都没法访问到[[prototype]],但能够经过isPrototypeOf()方法来肯定对象之间是否存在这种关系。从本质上讲,若是[[prototype]]指向调用isPrototypeOf()方法的对象(Person.prototype),那么这个方法就返回true,以下所示:prototype
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()能够方便的取得一个对象的原型,而这在利用原型实现继承(稍后会有文章更新)的状况下是很是重要的。code
虽然能够经过对象实例访问保存在原型中的值,但却不恩可以经过对象实例重写原型中的值,若是咱们再实例中添加了一个属性,而该属性与实例原型中的一个属性同名,那咱们就在实例中建立该属性,该属性将会屏蔽原型中的那个属性。来看下面的例子:对象
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。图片