【JS】ES3中的继承
本人在学习ES3原型继承的时候,碰到两种继承方式的例子,记录一下,主要是用来对比两种方式谁的方式更好,也方便对原型和原型链这方面更进一步的学习和理解。
继承方式
先来看看第一种继承方式
function Teacher() {
this.name = 'Mr. Li';
this.tSkill = 'JAVA';
}
Teacher.prototype = {
pSkill: 'JS/JQ'
}
var t = new Teacher();
console.log(t);
function Student() {
this.name = 'Mr. Wang';
}
Student.prototype = Teacher.prototype;
Student.prototype.age = '18';
var s = new Student();
console.log(s);
打印结果:

给Student的原型上添加"age"属性,发现Teacher的原型上也多了"age"属性,说明这样的继承方式修改子辈原型上的属性,父辈上的原型上的属性也会被修改。
为了避免这种情况,第二种继承方式在Teacher和Student中间增加一层Buffer缓冲区。
从下面可以看到第二种继承方式:
function Teacher(){
this.name = 'Mr. Li';
this.tSkill = 'JAVA';
}
Teacher.prototype = {
pSkill: 'JS/JQ'
}
var t = new Teacher();
console.log(t);
function Student(){
this.name = 'Mr. Wang';
}
function Buffer(){}
Buffer.prototype = Teacher.prototype;
var buffer = new Buffer();
Student.prototype = buffer;
Student.prototype.age = 18;
var s = new Student();
console.log(s);
打印结果:

此时可以发现在Teacher上的原型上没有"age"属性,说明这种方式并没有修改Teacher上的原型,是有效的。
实现原理
第一种方式:在age = 18 赋值的时候,由于Student的原型是拿的Teacher原型的地址引用,所以修改Student的原型,那么Teacher的原型也会跟着一起改。
第二种方式:又称圣杯模式,新建一个Buffer构造函数作为缓冲带,buffer实例对象在new的时候已经继承了Buffer构造函数的作用域,所以赋值的过程其实是给buffer实例对象上添加"age"属性。
要注意的是并不是在buffer.proto,也就是Buffer的对象原型(Buffer.prototype)上添加"age"属性。
封装继承方法
var inherit = (function(){
var Buffer = function(){}
return function(Target, Origin){
Buffer.prototype = Origin.prototype;
Target.prototype = new Buffer();
Target.prototype.constructor = Target;
Target.prototype.super_class = Origin;
}
})();
Teacher.prototype.name = 'Mr. Zhang';
function Teacher(){}
function Student(){}
inherit(Student, Teacher);
var s = new Student();
var t = new Teacher();
console.log(s);
console.log(t);

浙公网安备 33010602011771号