文章目录
  1. 1. 理解原型模式
  2. 2. 两种实现方式
    1. 2.1. 直接在原型对象里面添加属性和方法
    2. 2.2. 重写原型对象
  3. 3. 原型链的继承

理解原型模式

原型模式简单点说就是各个实例共享一个原型对象。JavaScript实现原型模式非常简单,直接用个prototype就实现了。新建实例里面保存了指针指向同一个原型对象,而与构造函数没有关系,参考原型图:

两种实现方式

直接在原型对象里面添加属性和方法

因为各个实例要共享一个原型对象,所以就把构造函数中的属性和方法集中到一个对象就可以了,如:

1
2
3
4
5
6
7
function Student() {};
Student.prototype.name = 'foo';
Student.prototype.age = '1';
Student.prototype.say = function() {console.log('hehe')}
var student = new Student();
student.say();//输出hehe
console.log(student.constructor);//输出构造函数Student

Student.prototype就是看做原型对象,在里面分别添加属性和方法就可以了。从上图中看到构造函数Student有一个prototype属性,这个属性就是指向原型对象Student.prototype的指针,执行student.say()这个实例方法,会先从实例对象student属性中去找有没有这个方法,如果没有再到原型对象里面去查询。

重写原型对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function Student() {};
var student1 = new Student();
console.log(student1.name);//输出undefined
console.log(student1.age);//输出undefined
console.log(student1.say)//输出undefined,没有重写原型对象之前,指针还是只想原来的原型对象
Student.prototype = {
//constructor: Student,//强制将构造函数修改为Student
name:'foo',
age : '1',
say : function() {
console.log('hehe');
}
}
var student2 = new Student();
console.log(student2.say);//重写原型对象之后,新实例化对象指向重写后的原型对象
console.log(student2.constructor);//重写原型对象后,构造函数变成了Object
Student.prototype.foo = function() {};
console.log(student2.foo);

需要注意的是,如果在开始还没有重写原型对象时,实例化的对象是不能访问重写后Student.prototype里面的内容的,参考实例student1打印结果;如果重写了原型对象,再实例化student2,然后再对原型对象添加属性,student2是可以获得最新的原型对象,因为student2中只是保存的是重写后的原型对象指针,所以不管原型对象怎么修改,student2中的指针始终指向重写后的原型对象,如下图所示:

原型链的继承

原型链继承记住一点就可以了,就是直接重写原型对象。其实前面重写Student原型对象就有点原型链的意思了,只不过是继承的Object不太容易看出来。下面定义两个对象,一个父对象,一个子对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function Father() {
this.fvalue = 'father';
}
Fathor.prototype.getFatherValue = function() {
return this.fvalue;
}

function Child() {
this.cvalue = 'child';
}
Child.prototype.getChildValue = function() {
return this.cvalue;
}

//与前面的重写Student.prototype是不是有点相似了
//这里不要加var,不然会先加载var变量,执行的时候就找不到Father了
Child.prototype = new Father();

var child = new Child();
console.log(child.getFatherValue());//输出father

参考资料:

-《JavaScript高级程序设计第三版》

文章目录
  1. 1. 理解原型模式
  2. 2. 两种实现方式
    1. 2.1. 直接在原型对象里面添加属性和方法
    2. 2.2. 重写原型对象
  3. 3. 原型链的继承