欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

继承学习之类式继承、构造函数式继承、组合继承代码实例

程序员文章站 2022-03-22 12:53:46
继承: 指的是子类继承父类的属性和方法。 子类是父类的实例 子类继承父类的属性和方法,可以使用父类的属性和方法,又不影响父类原型上的方法 父类不能使用子类独有的属性和方法...

继承: 指的是子类继承父类的属性和方法。

子类是父类的实例

子类继承父类的属性和方法,可以使用父类的属性和方法,又不影响父类原型上的方法

父类不能使用子类独有的属性和方法

继承方式:

①类式继承 或者 原型式继承

②构造函数式继承

③组合式继承

1. instanceof

该关键字用于判定某一个对象是否是某一个构造函数的实例

使用方式:

对象instanceof构造函数

2. 类式继承 或者 原型式继承(用于继承方法)

类式继承:也叫做原型式继承。 将子类的原型指向父类的实例。

真正意义上的继承:

子类继承了父类,子类是子类构造函数的实例,子类也是父类构造函数的实例,子类可以使用父类的方法并且不影响父类的方法 ,父类不可以使用子类的方法

注意:

①类式继承 或者 原型式继承的弊端:

这种继承会丢失原来的子类原型的constructor属性,而原来的子类原型上是有一个constructor属性的。要记得补回。

② 子类的新的方法的赋值语句一定要写在原型式继承代码的下方。

<!doctype html>  
<html lang="en">  
<head>  
    <meta charset="utf-8">  
    <title>document</title>  
</head>  
<body>  
    <script type="text/javascript">  
    // 父类  
    // function people(name, age, sex) {  
    //  this.name = name;  
    //  this.age = age;  
    //  this.sex = sex  
    // }  
    // // 父类的方法  
    // people.prototype.sayhello = function() {  
    //  console.log("我的名字叫做" + this.name)  
    // }  
  
  
    // // 子类  
    // function student(name, age, sex, grade) {  
    //  this.name = name;  
    //  this.age= age;  
    //  this.sex = sex;  
    //  this.grade = grade;  
    // }  
    // // 所谓继承, 就是应该是子类从父类的上面得到一些东西。  
    // // 现在我们想让子类调用父类的方法,我们能想到最简单的方法就是让子类的原型指向父类的原型。  
    // // 尝试1:  
    // student.prototype = people.prototype;  
    // // 既然是子类, 就应该拥有和父类不一样的方法。  
    // // 给子类添加方法  
    // student.prototype.intro = function() {  
    //  console.log("我的年纪" + this.age +"了");  
    // }  
  
    // // 实例化  
    // var people = new people("小明", 25, "男");  
    // var student = new student("小红", 12, "女", 6);  
  
    // // 测试子类是够能够调用父类的方法  
    // // student.sayhello();  
  
    // // 测试父类能否调用子类的方法  
    // people.sayhello();  
    // people.intro();  
  
    // 经过测试, 子类确实可以访问父类的方法了, 但是父类同时也可以调用子类的方法。  
    // 我们现在迫切需要一种方法, 既可以让子类继承父类的方法, 又不影响父类原型上的方法。  
  
  
  
    /***************************************************************************/  
  
    function people(name, age, sex) {  
        this.name = name;  
        this.age = age;  
        this.sex = sex  
    }  
    // 父类的方法  
    people.prototype.sayhello = function() {  
        console.log("我的名字叫做" + this.name)  
    }  
  
  
    // 子类  
    function student(name, age, sex, grade) {  
        this.name = name;  
        this.age= age;  
        this.sex = sex;  
        this.grade = grade;  
    }  
  
    student.prototype = new people();  
    // student.prototype = {  
    //      constructor: student  
    // }  
    // 此时, student的constructor 属性丢失。  
    // 继承之后,要记得手工补回原有的constructor 属性,并且给student添加的新方法要写在此条代码的后面。  
    student.prototype.constructor = student;  
    // 给子类添加方法  
    student.prototype.intro = function() {  
        console.log("我的年纪" + this.age +"了");  
    }  
    // 现在我们不能让子类的原型指向父类的原型了  
    // 现在我们想到 让子类的原型指向父类的实例,这个方法符合我们的要求。  
  
    var people = new people("小明", 25, "男");  
    var student = new student("小红", 12, "女", 6);  
    // 测试子类是否继承了父类的方法  
    // student.sayhello();  
    // 测试父类能否使用子类的方法  
    // people.intro();  
  
    // 最后测试, 是否是继承了父类  
    console.log(student instanceof student);  
    console.log(student instanceof people);  
    </script>  
</body>  
</html>  

向原型对象添加多种方法:

<!doctype html>  
<html lang="en">  
<head>  
    <meta charset="utf-8">  
    <title>document</title>  
</head>  
<body>  
    <script type="text/javascript">  
    // 父类  
    function people(name, age, sex) {  
        this.name = name;  
        this.age = age;  
        this.sex = sex;  
    }  
    // 添加一种方法  
    people.prototype.sayhello = function() {  
  
    }  
    // 添加10种方法  
    people.prototype = {  
        // 记得手工补回constructor 属性。  
        constructor: people,  
        say: function() {  
  
        },  
        hehe: function() {  
  
        },  
        haha: function() {  
  
        }  
    }  
    </script>  
</body>  
</html>  

3. 构造函数式继承(用于继承属性)

在子类的构造函数中,调用父类的构造函数并使用apply将父类构造函数的this指向子类的this,并将arguments传递进去。

注意:所有的子类特有属性赋值语句都要放在构造函数继承代码的下面。

构造函数式继承:

子类并不是父类的实例,子类可以继承父类的属性

<!doctype html>  
<html lang="en">  
<head>  
    <meta charset="utf-8">  
    <title>document</title>  
</head>  
<body>  
    <script type="text/javascript">  
    // 之前我们讲的是继承了父类的方法, 这种“子类的原型指向父类的实例的继承方式” 叫做类式继承或者原型式继承。  
    // 我们将如何继承属性  
    // 父类  
    function people(name, age, sex) {  
        this.name = name;  
        this.age = age;  
        this.sex = sex;  
    }  
    // 子类  
    function student(name, age, sex, grade) {  
        // var arr = [].slice.call(arguments);  
        people.apply(this, arguments);  
        this.grade = grade;  
    }  
    var s = new student("小明", 12, "男", 6)  
    console.log(s)  
    console.log(s instanceof people);  
  
  
    // 每个函数都有一个prototype属性, 它是一个对象, 对象里面有一个constructor 属性 指向构造函数本身  
    // console.log(student.prototype)  
    </script>  
</body>  
</html>  

4. 组合继承(继承属性和方法)

构造函数式继承 + 类式继承/原型式继承

<!doctype html>  
<html lang="en">  
<head>  
    <meta charset="utf-8">  
    <title>document</title>  
</head>  
<body>  
    <script type="text/javascript">  
    // 父类  
    function people(name, age, sex) {  
        this.name = name;  
        this.age = age;  
        this.sex = sex;  
    }  
    // 子类  
    function student(name, age, sex, grade) {  
        // var arr = [].slice.call(arguments);  
        people.apply(this, arguments);  
        this.grade = grade;  
    }  
    // student.prototype = {  
    //      constructor: student  
    // }  
    // 此时, student的constructor 属性丢失。  
    student.prototype = new people();  
    // 我们可以手动补回  
    student.prototype.constructor = student; // 继承之后, 要记得手工补回原有的constructor 属性,并且给student添加的新方法要写在此条代码的后面。  
  
  
    var s = new student("小明", 12, "男", 6)  
    console.log(s.constructor)  
    </script>  
</body>  
</html>