理解原型模式
原型模式简单点说就是各个实例共享一个原型对象。JavaScript实现原型模式非常简单,直接用个prototype就实现了。新建实例里面保存了指针指向同一个原型对象,而与构造函数没有关系,参考原型图:
两种实现方式
直接在原型对象里面添加属性和方法
因为各个实例要共享一个原型对象,所以就把构造函数中的属性和方法集中到一个对象就可以了,如:
1 2 3 4 5 6 7
| function Student() ; Student.prototype.name = 'foo'; Student.prototype.age = '1'; Student.prototype.say = function() var student = new Student(); student.say(); console.log(student.constructor);
|
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); console.log(student1.age); console.log(student1.say) Student.prototype = { name:'foo', age : '1', say : function() { console.log('hehe'); } } var student2 = new Student(); console.log(student2.say); console.log(student2.constructor); 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; }
Child.prototype = new Father();
var child = new Child(); console.log(child.getFatherValue());
|
参考资料:
-《JavaScript高级程序设计第三版》