美文网首页javascript设计模式笔记
JavaScript进阶:类式继承和构造函数继承

JavaScript进阶:类式继承和构造函数继承

作者: 听书先生 | 来源:发表于2022-01-11 22:58 被阅读0次
1、类式继承

类的原型对象的作用就是为类的原型添加共有方法,但是类不能直接访问这些属性和方法,必须通过原型prototype来访问,而我们实例化一个父类的时候,新创建的对象复制了父类的构造函数内的属性和方法并且将原型__proto__指向了父类的原型对象,这样就拥有了父类的原型对象上的属性和方法,并且这个新创建的对象可以直接访问父类原型对象上的属性与方法。
当把父类赋值到子类的原型对象上去时,子类的原型就可以去访问父类原型对象上的属性和方法以及父类构造函数中复制的属性和方法。这便是类式继承的原理。

个人理解-图1.png
  • 代码举例:
// 创建一个父类
function ParentClass() {
    this.userName = 'e-kr';
}
// 在父类的原型对象上增添共有方法
ParentClass.prototype.getUserName = function() {
    return this.userName;
}
// 创建一个子类
function ChildClass() {
    this.cusName = 'c-af'
}
// 将父类赋值到子类的原型上去
ChildClass.prototype = new ParentClass();
ChildClass.prototype.getCusName = function() {
    return this.cusName;
}
// 实例化子类对象
const child = new ChildClass();
// 子类的实例对象调用父类的方法
const cusName = child.getCusName(); // 'c-af'
const userName = child.getUserName(); // 'e-kr'
// instanceof
const ralation = child instanceof ParentClass; // true
const ralate = ChildClass.prototype instanceof ParentClass; // true
  • instanceof检测:
    instanceof是通过判断对象的prototype原型链来确定这个对象是否是属于这个类的实例,而不关心对象与类的自身的结构。(也就是说是判断前面的对象是否是后面类的实例,也就是说并不指二者之间存在继承)

  • 类式继承的缺陷:
    由于子类通过其原型prototype对父类实例化,继承了父类,所以说,子类的实例对象在使用父类的引用属性时,只要一个子类的实例化对象修改了父类的引用类型,其他的子类的实例化对象拿到的都将是修改后的引用类型数据,也就是说,存在了数据共享,开发中就会导致问题。
    举例:

function ParentClass() {
    this.userName = 'e-kr';
    this.array = ['react', 'vue', 'angular'];
}
ParentClass.prototype.getUserName = function() {
    return this.userName;
}

function ChildClass() {
    this.cusName = 'c-af'
}
ChildClass.prototype = new ParentClass();
ChildClass.prototype.getCusName = function() {
    return this.cusName;
}
const child1 = new ChildClass();
const child2 = new ChildClass();

console.log(child2.array); // child1修改引用类型之前child2拿到的数据
child1.array.push('jquery');
console.log(child2.array); // child1修改引用类型之后child2拿到的数据
图2.png
2、构造函数继承

通过call()方法更改函数的作用环境,在子类中调用这个方法将子类中的变量在父类中执行一遍,由于父类中是给this绑定属性的,因此子类也就继承了父类的共有属性,由于该继承方法没有通过prototype继承,因此子类修改父类的引用类型数据不会修改父类中的。

function SuperClass(name) {
    this.name = 'e-kr'; // 在父类中写死name,测试子类中的name是否经过此次赋值操作
    this.array = ['react', 'vue', 'angular'];
}

function SuberClass(name) {
    SuperClass.call(this, name);  // 将子类中的name仍进父类中跑一遍(进行一次变量赋值)
}
SuperClass.prototype.getSuperName = function() {
    return this.name;
}
const sup = new SuperClass('e-af');
console.log(sup.getSuperName());
console.log(sup.name);
const sub1 = new SuberClass('e-gp');
const sub2 = new SuberClass('e-ar');
console.log(sub1.name); // 同样的打印的e-kr, 说明子类的name被放在父类中执行了一遍
//console.log(sub1.getSuperName()); // sub1.getSuperName is not a function
console.log(sub1.array); // sub2修改引用类型之前sub1拿到的数据
sub2.array.push('demo');
console.log(sub1.array); // sub2修改引用类型之后sub1拿到的数据
图3.png
打印出来的结果是未受影响的,可以看出这个继承方式是解决了上一个类式继承的缺陷,但是,这个继承方式也引申了一个更严重的问题,同时也就是构造函数继承的精髓的部分SuperClass.call(this, name);,目前是将变量放入父类中执行,因此,这种方法是无法继承到父类的方法的。因此,我们在子类实例化对象的时候尝试着去拿,是出现报错,提示not a function。

相关文章

  • js的继承方式

    1 类式继承 子类的原型对象 2 构造函数继承 创建即继承 3 组合继承 (类式继承和构造函数...

  • js继承方式

    类式继承 构造函数继承 组合继承 类式继承 + 构造函数继承 原型式继承 寄生式继承 寄生组合式继承 寄生式继承 ...

  • 【重学前端】JavaScript中的继承

    JavaScript中继承主要分为六种:类式继承(原型链继承)、构造函数继承、组合继承、原型式继承、寄生式继承、寄...

  • JavaScript进阶:类式继承和构造函数继承

    1、类式继承 类的原型对象的作用就是为类的原型添加共有方法,但是类不能直接访问这些属性和方法,必须通过原型prot...

  • js 继承

    构造函数继承 类式继承是在函数对象内调用父类的构造函数,使得自身获得父类的方法和属性。call和apply方法为类...

  • java中继承,子类是否继承父类的构造函数

    java中继承,子类是否继承父类的构造函数 java继承中子类是不会继承父类的构造函数的,只是必须调用(隐式或者显...

  • Dart(6)类

    类的定义和使用,构造函数,对象的类型 记住构造函数是不能被继承的,这将意味着子类不能继承父类的命名式构造函数,如果...

  • JavaScript的六种继承方式

    JavaScript的几种继承方式 原型链继承 借助构造函数继承(经典继承) 组合继承:原型链 + 借用构造函数(...

  • javaScript 实现继承方式

    JavaScript实现继承共6种方式:原型链继承、借用构造函数继承、组合继承、原型式继承、寄生式继承、寄生组合式继承。

  • #js继承

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

网友评论

    本文标题:JavaScript进阶:类式继承和构造函数继承

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