Javascript继承的实现方式总结

总结归纳了6种js的继承实现方式并分析了其中实现的区别,为了解释,定义一个作为的父类的类型Animal,之后定义的类都为Animal类的子类,实现方式不同,Animal类代码如下:

function Animal(name) {
    this.name = name;
    this.color = 'blue';
}

Animal.prototype.sayName = function () {
    console.log(this.name);
};

复制代码

1 简单的原型链继承方式

这种是最简单的实现继承的方式,即使子类的原型对象等于父类的一个新的实例对象,举例代码如下:

// 1.原型链继承
function Cat() {
}
Cat.prototype = new Animal();
复制代码

这样即实现了Cat类对Animal类的继承,其中存在的问题是Cat的原型对象中会有Animal类的构造函数中的属性如上例中的color属性,而这个属性是不必要的。而且Cat.prototype的constructor属性也是指向Animal的。实现继承后关系如图所示:

2 借用构造函数继承

借用构造函数继承也叫伪造对象继承或者经典继承,其主要实现方式是在子类的构造函数中调用父类的构造函数,示例代码如下:

// 2.借用构造函数,经典继承
function Dog() {
    // 继承Animal,并传递参数
    Animal.call(this, 'doge');
}
var instance = new Dog();
复制代码

这种方式的好处是可以向父类传递参数,而且父类的原型对象中的属性及方法对子类型也是不可见的,所以这种方法很少单独使用。

3 组合继承

这种继承的方式结合了借用构造函数继承和简单的原型链继承,示例代码如下:

// 3.组合继承
function Mouse() {
    Animal.call(this, 'jerry');
}
// 继承方法
Mouse.prototype = new Animal();
Mouse.constructor = Mouse;
复制代码

这种继承方式是js中最常用的继承模式,但是其中仍然没有解决原型链继承问题中存在的子类原型对象中存在父类构造函数中属性的问题。

4 原型式继承

这种继承方式主要针对与不关注自定义类型和构造函数而考虑对象的情况下,思路是基于已有的对象创建新对象,实例代码如下:

// 4.原型式继承
function object(o) {
    function F() {}
    F.prototype = o;
    return new F();
}

var bird1 = object(Animal);
复制代码

这种继承方式通过临时创建一个新的构造函数F并将其原型对象设为所需要的对象,然后返回一个此构造函数F的实例以实现继承。关系图如下:

而在ES5中提供了新的方法 Object.create()规范化了原型式继承,上面的代码可以改为:

var bird2 = Object.create(Animal, {number: {value: 3}});
复制代码

同时在Object.create()中可以在第二参数中实现定义额外的属性,bird2相对bird1多了一个value属性。在只有一个参数时上方定义的object()函数和Object.create()函数行为相同。

5 寄生式继承

这种继承方式使用了Object.create(),创建一个用于封装继承过程的函数,在函数内部来增强对象,其本质原理与原型式继承类似,示例代码:

// 5.寄生式继承
function createAnother(original) {
    var clone = Object.create(original);
    clone.sayHi = function () {
        console.log('hi');
    };
    return clone;
}

var anotherAnimal = createAnother(Animal);
anotherAnimal.sayHi();
复制代码

6 寄生组合式继承

寄生组合式继承是最理想的继承范式,通过借用构造函数来继承属性通过原型链来继承方法。本质上使用了寄生式继承来继承超类型的原型,然后将结果指定给子类型的原型。实例代码如下:

// 6.寄生组合式继承
function inheritPrototype(subType, superType) {
    // 创建对象
    var prototype = Object.create(superType.prototype);
    // 增强对象
    prototype.constructor = subType;
    // 指定对象
    subType.prototype = prototype;
}

function Fish(name) {
    Animal.call(this, 'fish');
}

inheritPrototype(Fish, Animal);
复制代码

使用结果示意图如下:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JavaScript 中,继承是一个非常常见的概念。ES6 引入了 Class 语法糖,让继承更加易于理解和实现。在 Class 中,我们可以使用 extends 关键字来创建一个子类,使其继承父类的属性和方法。 下面我们来详细了解一下如何在 JavaScript 中使用 extends 实现继承。 ### 基础语法 首先,我们需要定义一个父类。在 ES6 中,我们可以使用 Class 来定义一个类。例如: ```javascript class Animal { constructor(name) { this.name = name; } speak() { console.log(this.name + ' makes a noise.'); } } ``` 这个 Animal 类有一个构造函数和一个 speak 方法。构造函数会在创建实例时被调用,而 speak 方法则可以让动物发出一些声音。 接下来,我们来创建一个子类。使用 extends 关键字来创建子类,并使用 super() 方法调用父类的构造函数。例如: ```javascript class Dog extends Animal { constructor(name) { super(name); } speak() { console.log(this.name + ' barks.'); } } ``` 这个 Dog 类继承了 Animal 类,并覆盖了其 speak 方法。在构造函数中,我们通过 super() 方法来调用父类的构造函数,并将传递的参数传递给它。 现在,我们可以创建一个 Dog 的实例,并调用其 speak 方法: ```javascript let d = new Dog('Mitzie'); d.speak(); // Mitzie barks. ``` ### 继承父类的方法 当一个子类继承了一个父类时,它会继承父类的属性和方法。例如,在上面的例子中,Dog 类继承了 Animal 类,因此它继承了 Animal 类的 speak 方法。 当我们调用子类的方法时,如果子类没有实现该方法,它会自动调用父类的方法。例如,在上面的例子中,如果我们不覆盖 Dog 类的 speak 方法,它将调用 Animal 类的 speak 方法。 ### 覆盖父类的方法 如果一个子类需要覆盖父类的方法,我们可以在子类中重新定义该方法。例如,在 Dog 类中,我们覆盖了 Animal 类的 speak 方法,使其输出“barks”而不是“makes a noise”。 ### 调用父类的方法 有时候,我们需要在子类中调用父类的方法。我们可以使用 super 关键字来调用父类的方法。例如,在 Dog 类中,我们可以通过调用 super.speak() 来调用 Animal 类的 speak 方法。 ### 总结 继承是一个非常常见的概念,也是面向对象编程中的重要概念之一。在 JavaScript 中,我们可以使用 extends 关键字来实现继承。通过继承,子类可以继承父类的属性和方法,也可以覆盖父类的方法,并且可以调用父类的方法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值