JavaScript之继承

继承的五种方式

概念:子类型继承父类型的属性和方法。

作用:减少代码量。

一、通过属性copy实现继承

对象的‘继承’本质是对象的拷贝,把一个对象的所有成员拷贝到另一个对象中。

代码演示:

// 第一个对象
var obj1 = {name ;'zs',age:18};
// 第二个对象
var ojb2 = {
  name: 'ls',
  age: 18,
  gender: '男',
  sayHi:function () {
    conselo.log('大家好' + this.name);
  }
}
// 把一个对象的属性和方法,拷贝到另一个对象中去
function extend(parent,child) {
  for ( var key in parent) {
    if (child[key] === undefined) {
      child[key] = parent[key];
    }
  }
}
// 拷贝之前的obj1
console.log(obj1); // {name: "张三", age: 18}
// 把obj2中的属性或方法拷贝到obj1中
extend(obj2,obj1);
// 拷贝之后的obj1
console.log(obj1); // {name: "张三", age: 18, sex: "男", sayHi: ƒ}

二、原型继承

类型与类型之间的关系。

代码演示:学生类型、老师类型继承Person类型。

// 人的构造函数
function Person () {
    this.name = '名字';
    this.age = 18;
}
Person.prototype.sayHi = function() {
    alert('大家好,我叫' + this.name);
};

// 学生构造函数
function Student (stuId) {
    this.stuId = stuId;
}
// 老师构造函数
function Teacher (money) {
    this.money = money;
}

// 通过学生的原型让学生继承人
Student.prototype = new Person();  // 无法设置构造函数的参数
// 当设置了构造函数的prototype之后,别忘记设置constructor
Student.prototype.constructor = Student;
// 通过老师的原型让老师继承人
Teacher.prototype = new Person();
Teacher.prototype.constructor = Teacher;
// 创建学生对象
var stu1 = new Student(10010);
console.log(stu1);
// 创建老师对象
var t1 = new Teacher(100);
console.log(t1);

缺点:通过原型对象的属性是没有意义的,因为无法为每一个实例创建的对象传入参数。

三、借用构造函数继承

call函数:把一个函数调用给调用者,立即执行

语法:函数名.call(调用者,实参1,实参2,实参3...);

执行了函数名中的内部程序,并没有执行它的原型,所以只是克隆了函数名的属性。

function fn2 (num1,num2,num3) {
    console.log(num1,num2,num3);
    console.log(this);
}
fn2(1,2,3);  // this→ window
var obj = {name:'调用者'};
fn2.call(obj,4,5,6)

四、组合继承

 // 人类
 function Person (name,age,gender) {
     this.name = name;
     this.age = age;
     this.gender = gender;
 }
     Person.prototype.sayHi = function () {
     console.log('大家好');
 };

 // 学生类
 function Student(name, age, gender, studId) {
     // this在这里指向调用者   stu1
     var dyz = this;
     // 调用Person借给当前创建的学生对象 【① 借用继承 实现了继承属性】
     Person.call(dyz,name, age,gender);
     this.studId = studId;
 };
    // 【② 原型继承 实现了继承方法 】
     Student.prototype = Person.prototype;
    Student.prototype.constructor = Student;
    // 给学生单独加上一个特有的考试方法
    Student.prototype.exam = function () {
     console.log('学生考试');
 };

 //老师类
function Teacher(name, age, gender, money) {
    var dyz = this;
    this.money = money;
    // ① 借用继承Person中的属性
    Person.call(dyz, name,age,gender);
}
    // ② 原型继承Person原型中的方法
    Teacher.prototype = Person.prototype;
    Teacher.prototype.constructor = Teacher;

    // 创建学生对象
    var stu1 = new Student('张三',17,'男',10086);
    console.log(stu1);
    stu1.sayHi(); 

    // 创建老师对象
    var t1 = new Teacher('王五', 18, '男', 100);
    console.log(t1);
// 缺点:给学生的原型上添加一个考试exam方法时,老师中也会多一个考试exam方法。
// 原因:学生原型 和 老师原型 指向同一个Person原型

五、借用和对象拷贝

      function extend(parentObj, childObj) {
        for (var key in parentObj) {
          // 如果子对象中不存在这个属性或方法,则再去拷贝
          if (childObj[key] === undefined) {
            // 把父对象中的属性或方法赋值给子对象
            childObj[key] = parentObj[key]
          }
        }
      }
      // 人类
      function Person(name, age, gender) {
        this.name = name
        this.age = age
        this.gender = gender
      }
      Person.prototype.sayHi = function () {
        console.log('大家好')
      }

      // 学生类
      function Student(name, age, gender, studId) {
        // this在这里指向调用者   stu1
        var dyz = this
        // 调用Person借给当前创建的学生对象 【① 借用继承 实现了继承属性】
        Person.call(dyz, name, age, gender)
        this.studId = studId
      }
      // 【② 对象的拷贝 实现了继承方法 】 把人类(父对象)原型对象中方法 拷贝到 学生(子对象)类原型对象中
      extend(Person.prototype, Student.prototype)
      // 给学生增加考试的方法
      Student.prototype.exam = function () {
        console.log('学生考试')
      }

      //老师类
      function Teacher(name, age, gender, money) {
        var dyz = this
        // this
        this.money = money
        // ① 借用继承Person中的属性
        Person.call(dyz, name, age, gender)
      }
      // 【② 对象的拷贝 实现了继承方法 】 把人类(父对象)原型对象中方法 拷贝到 老师(子对象)类原型对象中
      extend(Person.prototype, Teacher.prototype)

      // 创建学生对象
      var stu1 = new Student('张三', 17, '男', 10086)
      // 给学生单独加上一个特有的考试方法,不会出现在老师类中
      Student.prototype.exam = function () {
        console.log('学生考试')
      }
      console.log(stu1)
      
      // 创建老师对象
      var t1 = new Teacher('王五', 18, '男', 100)
      console.log(t1)

原文地址:https://www.cnblogs.com/houfee/p/9123955.html