JS继承

作者: 苹果咏 | 来源:发表于2019-07-11 17:57 被阅读0次

1、prototype继承
prototype对象包含所有实例对象需要共享的属性和方法,那些不需要共享的属性和方法就放在构造函数里。
实例对象一旦创建,将自动引用prototype对象的属性和方法。
以dog构造函数举例:

function dog(name){
  this.name = name;
}
dog.prototype = { species:'狗' };
var dogA = new dog('小黑');
var dogB = new dog('小黄');

alert(dogA.species); // 狗
alert(dogB.species); // 狗

优点:
父类的方法得到了复用。

缺点:
原型中属性的改变会反应到所有的实例上
创建子类的实例时,不能向父类的构造函数传递参数

2、使用 class 语法糖继承

class Person{
  constructor(name, sex){
    this.name = name;
    this.sex = sex;
  }
}

class Man extends Person{
  constructor(name){
    super('','male');
    this.name = name;
  }
}

let Lee = new Man('Lee')
console.log(Lee.name, Lee.sex) // Lee male

3、利用父构造函数继承属性

function Father(uname, age){
    this.uname = uname;//这里this指向父构造函数
    this.age = age
}
function Son(uname, age,score,job){
    Father.call(this, uname, age)//调用父构造函数,这里的this一定要写在第一个,而且可以表示多个参数
        this.score = score//自己的属性
        this.job= job
}
var son = new Son('李丽',18,100,'学生')
console.log(son)//Son {uname: "李丽", age: 18,score:100,job:"学生"}

4、利用原型对象继承方法

// 借用父构造函数继承属性
        // 1. 父构造函数
        function Father(uname, age) {
            // this 指向父构造函数的对象实例
            this.uname = uname;
            this.age = age;
        }
        Father.prototype.money = function() {
            console.log(100000);

        };
        // 2 .子构造函数 
        function Son(uname, age, score) {
            // this 指向子构造函数的对象实例
            Father.call(this, uname, age);
            this.score = score;
        }
        // Son.prototype = Father.prototype;  这样直接赋值会有问题,如果修改了子原型对象,父原型对象也会跟着一起变化
        Son.prototype = new Father();
        // 如果利用对象的形式修改了原型对象,别忘了利用constructor 指回原来的构造函数
        Son.prototype.constructor = Son;
        // 这个是子构造函数专门的方法
        Son.prototype.exam = function() {
            console.log('孩子要考试');

        }
        var son = new Son('刘德华', 18, 100);
        console.log(son);
        console.log(Father.prototype);
        console.log(Son.prototype.constructor);

5、ES6继承

class Calculator {
        constructor(a,b){
            this.a = a;
            this.b = b;
        }
        add(a,b){
            return ("相加結果:"+ (a+b))
        }
    }
    class Son extends Calculator{
        add(a,b){
            console.log(super.add(a,b))
        }
    }
    var rt = new Son()
    rt.add(3, 4)

super.add(a,b)就是调用父类中的普通函数


继承中属性和方法的查找原则是就近原则:

class Calculator {
        add(){
            console.log ("我是父親")
        }
    }
    class Son extends Calculator{
        add(){
            console.log ("我是兒子")
        }
    }
    var son = new Son()
    son.add()//我是兒子



子类扩展函数,并调用父类的构造函数:

class Calculator {
        constructor(a,b){//構造函數
            this.a = a;
            this.b = b;
        }
        add(a,b){//普通函數
            console.log ("相加結果:"+ (a+b))
        }
    }
    class Son extends Calculator{
        constructor(a,b,c){
            //利用super調用父類構造函數,super必須在this之前,爹是最大的
            this.c = c //ReferenceError
            super(a,b)
            this.c = c // 正确
        }
        reduce(a,b,c){
            console.log ("相減結果:"+ (a-b-c))
        }
    }
    var rt = new Son()
    rt.add(3, 4)
    rt.reduce(3, 4)



this指向问题,谁调用,this就指向谁:

var _that
    class Calculator {
        constructor(a,b){//构造函数
            _that = this//将constructor的this给that
            this.a = a;
            this.b = b;
            document.querySelector('button').onclick = this.add
        }
        add(){
            //这里的this指向的是button按钮,谁调用,this就指向谁
            //我们要的值是存在constructor中,所以用that将constructor弄过来
            console.log(this)
            console.log ("相加結果:"+ (_that.a+_that.b))
        }
    } 
    var rt = new Calculator(3,4)
image.png

ES6原型问题总结

//类的 prototype 属性和__proto__属性
class A {
}

class B extends A {
}

B.__proto__ === A // true   子类的__proto__属性,表示构造函数的继承,总是指向父类。
B.prototype.__proto__ === A.prototype // true   子类prototype属性的__proto__属性,表示方法的继承,总是指向父类的prototype属性。


//实例的 __proto__ 属性
//子类实例的__proto__属性的__proto__属性,指向父类实例的__proto__属性。也就是说,子类的原型的原型,是父类的原型。
var p1 = new A();
var p2 = new B();

p2.__proto__ === p1.__proto__ // false
p2.__proto__.__proto__ === p1.__proto__ // true

总结:
ES5中:
利用借用构造函数实现实例属性和方法的继承 ;
利用原型链或者寄生式继承实现 共享的原型属性和方法的继承 。

ES6中:
利用class定义类,extends实现类的继承;
子类constructor里调用super()(父类构造函数)实现 实例属性和方法的继承;
子类原型继承父类原型,实现原型对象上方法的继承。

相关文章

  • Js的继承

    js的继承 @(js)[继承, js, 前端] 组合继承是原性链继承和构造函数继承的合体,它汲取了二者各自的有点,...

  • JS继承

    JS中的继承 许多OO语言都支持两种继承方式:接口继承和实现继承; 因为JS中没有类和接口的概念 , 所以JS不支...

  • #js继承

    js继承的概念 js里常用的如下两种继承方式: 原型链继承(对象间的继承)类式继承(构造函数间的继承) 类式继承是...

  • js继承遇到的小问题

    这两天在看js继承方面,它不像OC那种传统的类继承。js继承方式还是挺多的。比如:原型继承、原型冒充、复制继承 原...

  • JS中继承的实现

    JS中继承的实现 #prototype (js原型(prototype)实现继承) 全局的Function对象没有...

  • js继承

    js继承js 继承-简书 原型链实现集继承 上面的代码实现原型链继承最重要的son.prototype=new f...

  • JavaScript 10

    js继承的概念 1.通过原型链方式实现继承(对象间的继承) 2.类式继承(构造函数间的继承) 由于js不像Java...

  • JS继承的实现的几种方式

    前言 JS作为面向对象的弱类型语言,继承也是非常强大的特性之一,那么如何在JS实现继承呢? JS继承的实现方式 既...

  • 2019-03-25 继承

    js中通过原型来实现继承 组合继承:原型继承+借用构造函数继承

  • 继承方式(6种)1.7

    JS作为面向对象的弱类型语言,继承也是其非常强大的特性之一。那么如何在JS中实现继承呢?让我们拭目以待。 JS继承...

网友评论

      本文标题:JS继承

      本文链接:https://www.haomeiwen.com/subject/wvodkctx.html