在《JavaScript创建对象(二)——构造函数模式》中提到,构造函数模式存在相同功能的函数定义多次的问题。本篇文章就来讨论一下该问题的解决方案——原型模式。
首先我们来看下什么是原型。我们在创建一个函数时,这个函数会包含一个属性`prototype`,这个属性是一个指针,它指向一个对象——该函数的原型对象,这就是原型,它包含了该函数类型的所有实例可共享的属性和方法,见下面示意图:

如图所示,声明了一个函数`Person`。在JavaScript中,一个函数被声明的同时就具有了一些属性,其中有一个叫做`prototype`,它指向了该函数的原型对象,即上述示例中的`Person Prototype`。同时,这个原型对象有一个叫做`constructor`的属性反过来又指向了该函数对象。
当我们创建一个函数的实例时,例如上面的`var personObj = new Person('张三', 12);`,这个实例也会有一个属性指向该函数的原型对象,在Chrome的开发工具中显示为`__proto__`。
上面我们说原型的属性可以被该函数类型的所有实例所共享,那具体是怎么实现呢?看下面的示例:
```javascript
function Person(){
}
//给原型添加自定义属性和方法
Person.prototype.name = '张三';
Person.prototype.sayName = function(){
console.log(this.name);
}
var p1 = new Person();
//给p1添加age属性
p1.age = 18;
console.log(p1.name);//张三
console.log(p1.age);//18
p1.sayName();//张三
var p2 = new Person();
console.log(p2.name);//张三
console.log(p2.age);//undefined
p2.sayName();//张三
```
在上面的代码中,我们并没有给实例添加`name`属性和`sayName`方法,但是依然可以通过实例调用,貌似实例天生就具有了原型的属性和方法,其实不是的,下面是在Chrome的开发工具中看到的内容:

网友评论