题外话:
只有自己尝试写个框架,才有机会接触像原型、作用域、事件代理、缓存系统、定时器等深层知识。
司徒正美《JavaScript框架设计》
起源
单独使用原型链继承:
- 优点,利用prototype实现了数据的共享,以此来实现继承。
- 缺点,当涉及到引用类型(比如说数组)的时候,一个实例修改了引用类型的值会影响到另一个实例,耦合性太强。
单独借用构造函数继承:
- 优点,子类可以向超类传参数。
- 缺点,方法都是在构造函数里定义的,无可复用性。
为此,才出现了组合继承。
基本概念
组合继承(combination inheritance),有时候也叫做伪经典继承,指的是将原型链和借用构造函数的技术组合到一块,从而发挥二者之长的一种继承模式。
实现思路
使用原型链实现对原型属性和方法的继承,而通过借用构造函数来实现对实例属性的继承。这样,既通过在原型上定义方法实现了函数复用,又能够保证每个实例都有它自己的属性。
//console控制台验证 //构造函数实现实例属性,构造函数的优点 function SuperType(name) { this.name = name; this.numbers = [1,2,3]; } //原型来定义方法,原型链的优点 SuperType.prototype.sayName = function () { alert(this.name); }; function SubType (name, age) { //继承属性 SuperType.call(this, name); this.age = age; } //继承方法 SubType.prototype = new SuperType(); //子类新定义的方法一定要在上面的继承代码之后,要不然新写的方法就没了 SubType.prototype.sayAge = function () { alert(this.age); } var instance1 = new SubType("MirrorAvatar", 3); instance1.numbers.push(33); instance1.numbers; // "[1,2,3,33]" instance1.sayName(); //MirrorAvatar instance1.sayAge(); //3 var instance2 = new SubType("Cindy", 4); instance2.numbers; //"[1,2,3]" instance2.sayName(); //Cindy instance2.sayAge(); //4
总结
组合继承避免了原型链和借用构造函数的缺陷,融合了它们的优点,成为JavaScript中最常用的继承模式。而且,instanceof和isPrototypeOf()也能够用于识别基于组合继承创建的对象。
相关推荐
在JavaScript的世界里,ES5(ECMAScript 5)是一种广泛使用的版本,它引入了许多特性,其中一种重要的设计模式就是组合继承。组合继承是通过借用构造函数来实现原型链的继承,同时结合了原型链继承和原型式继承,以...
- **继承属性(Inherited Property)**:对象通过其原型链继承的属性。 #### 三、记法与约定 ECMAScript 5.1 规范中详细介绍了记法和文法,这有助于开发者理解语言的语法结构。例如: - **语法和词法的文法**:...
组合继承是JavaScript中最常用的继承模式,它结合了构造函数继承和原型链继承,但同时也存在两次调用父类构造函数的问题,导致了不必要的属性复制。为解决这个问题,我们使用寄生组合式继承: ```javascript ...
扩展运算符`...`用于将数组或可迭代对象展开,可以用于函数调用、数组合并等场景。剩余参数`...args`允许我们将不定数量的参数收集到一个数组中。 ```javascript function sum(...numbers) { return numbers....
在JavaScript(ECMAScript)中,继承机制是通过多种方式实现的,包括但不限于原型链、构造函数借用、组合继承等。JavaScript的类并非传统意义上的类,而是通过函数来模拟的。当一个函数被用作构造函数时,它可以创建...
为了消除子类构造函数中父类引用导致的额外开销,可以使用寄生组合继承。它通过创建一个临时的父类实例,再将这个实例的属性赋值给子类的原型,而不是直接使用父类的引用。 ```javascript function Parent(name) { ...
组合继承 原型式继承 寄生式继承 寄生组合 原型链继承 相信小伙伴们都知道到原型链继承(ECMAScript 中描述了原型链的概念,并将原型链作为实现继承的主要方法),因为原型链继承非常的强大,但是也有它的缺点,...
组合继承避免了子对象共享父对象引用类型属性的问题,同时也继承了父对象原型链上的方法。其主要缺点是调用了两次父构造函数,一次是在创建子构造函数的原型时,另一次是在构造函数内调用父构造函数时。 4. 原型式...
在JavaScript的世界里,ES5是ECMAScript第五版的简称,它是JavaScript的一种标准规范,而ES6(也称为ES2015)引入了`class`语法糖来更方便地处理对象的创建和继承。然而,在ES5时代,我们没有`class`关键字,但可以...
JavaScript实现继承的方式有很多,如原型链继承、构造函数继承、组合继承、原型式继承、寄生式继承和寄生组合式继承等。下面将详细介绍这些继承方式的核心思想和实现方法。 1. 原型链继承 原型链是JavaScript实现...
它避免了组合继承中调用两次父类构造函数的问题,同时也保持了原型链不变。它通过创建一个仅包含父类原型属性和方法的副本,然后将这个副本赋值给子类的原型,实现了对父类属性和方法的继承。 通过这些继承模式,...
寄生组合式继承有效地解决了组合继承两次调用父类构造函数的问题,只调用一次,保留了原型链继承的优点,并且只创建了一个实例,大大减少了内存的开销。 ### class 关键字(ES6) 在 ES6 中引入了 class 关键字,...
组合继承结合了原型链继承和构造函数继承的特点,即通过原型链继承原型上的属性和方法,通过构造函数继承实例属性。这样既能实现属性和方法的共享,又保证了每个实例都有自己的属性。不过,组合继承的缺点是会调用两...
4. **寄生组合继承**:通过借用构造函数和原型链来避免重复创建对象的问题。 #### 二、基本类继承示例分析 根据题目中的部分代码示例,我们可以看到一个简单的类继承的实现: ```javascript function newClass() ...
组合继承结合了原型链继承和构造函数继承的优点,使用原型链继承原型上的属性和方法,而通过构造函数来继承实例属性。这种继承方式是目前最常用的继承方式。 4. 原型式继承 原型式继承允许我们基于已有的对象来创建...