原型模式:
我们创建的每一个函数都有一个prototype(原型)属性,这个属性是一个指针,指向
一个对象,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。
如果按字面意思来理解,prototype就是通过调用构造函数而创建的那个对象实例的
原型对象。
使用原型对象的好处就是可以让所有对象实例共享它所包含的属性和方法。换句话说,
不必再构造函数中定义对象实例的信息,而是可以将这些信息直接添加到原型对象中。
具体例子可见例1。
例1:
function Person(){}
Person.prototype.name="Tom";
Person.prototype.age="35";
Person.prototype.getName=function (){
alert(this.name);
}
var person1=new Person();
var person2=new Person();
person1.getName(); //Tom
person2.getName(); //Tom
person1.name="Bob";
person1.getName(); //Bob,修改其中一个对象的属性,并不会影响其他的对象
person2.getName(); //Tom
alert(person1.getName==person2.getName); //true
由例1可知,当把所有的方法和属性都添加到prototype属性中时(即是当所在的构造函数为
空时),仍然可以通过调用构造函数来创建新对象,而且新对象还具有相同的属性和方法。
区别于构造函数的是:新对象所具有的属性和方法是所有实例共享的。
1.理解原型对象的概念
无论什么时候,只要创建了一个新函数,就会根据一组特定的规则为该函数创建一个prototype
属性,这个属性指向函数的原型对象。在默认情况下,所有的原型对象都自动获得一个constructor
属性(构造函数)属性,这个属性是一个指向prototype属性所在函数的指针。以上面的例1为例,
Person.prototype.constructor==person,而通过这个构造函数,我们可继续为原型对象添加其他属性
和方法。
对于例1,我们可以通过 isPrototypeOf ( )方法来确定对象和实例之间是否存在prototype之间的引用;
例2:
alert(Person.prototype.isPrototypeOf(person1)); //true
ECMAScript5中新增了一个方法:Object.getPrototypeOf( ),该方法返回[[prototype]]的值。
例3:
alert(Object.getPrototypeOf(person1)==Person.prototype); //true
使用方法hasOwnProperty( )方法可以检测一个属性是存在于实例中还是存在于原型中。
例4:
alert(person1.hasOwnProperty("name")); //false,属性存在于原型中
person1.name="123";
alert(person1.hasOwnProperty("name")); //true,属性存在与实例中
注意:可以通过对象实例访问保存在原型中的值,但不能通过对象实例重写原型中的值。
原型模式的主要问题:
举例:
function Person(){}
Person.prototype.name=["Tom","Joe"];
Person.prototype.age="35";
Person.prototype.getName=function (){
alert(this.name);
}
var person1=new Person();
var person2=new Person();
person1.name.push("123");
person2.getName(); //Tom,Joe,123,与原型中不符合!
原型模式的最主要问题还是有共享的特点导致的,以上面的例子来说明:person1和
person2都是原型的实例,但却可以通过其中的一个实例来修改其中的原型属性,导致
共享的属性被更改。