【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);
posted @ 2021-05-09 16:04  razzh  阅读(106)  评论(0)    收藏  举报