zoukankan      html  css  js  c++  java
  • 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)

  • 相关阅读:
    Asp.net Json 解析 与 直接用ip访问返回josn
    mysql 时间函数
    Android之TelephonyManager类的使用案例
    android:screenOrientation的说明 固定屏幕显示方向
    在android.app.Application中定义全局变量
    Android开发实例详解之IMF(Android SDK Sample—SoftKeyboard)
    Android InputMethodManager输入法简介
    android ImageView的属性android:scaleType,即ImageView.setScaleType(ImageView.ScaleType)
    VS编译常见错误枚举01
    Visual C++ Samples-------------Code Project
  • 原文地址:https://www.cnblogs.com/houfee/p/9123955.html
Copyright © 2011-2022 走看看