《JavaScript设计模式》——2.4 老师不止一位——多继承

简介: 你知道,在JavaScript中继承是依赖于原型prototype链实现的,只有一条原型链,所以理论上是不能继承多个父类的。然而JavaScript是灵活的,通过一些技巧方法你却可以继承多个对象的属性来实现类似的多继承。

本节书摘来自异步社区《JavaScript设计模式》一书中的第2章,第2.4节,作者:张容铭著,更多章节内容可以访问云栖社区“异步社区”公众号查看

2.4 老师不止一位——多继承

“是这样呀,对了,我记得有一些面向对象语言中支持多继承,在JavaScript中能实现么?”

“嗯,不过是有一些局限性的。你知道,在JavaScript中继承是依赖于原型prototype链实现的,只有一条原型链,所以理论上是不能继承多个父类的。然而JavaScript是灵活的,通过一些技巧方法你却可以继承多个对象的属性来实现类似的多继承。”小铭接着说,“讲解多继承之前先跟你说一下当前很流行的一个用来继承单对象属性的extend方法。”

// 单继承 属性复制  
var extend = function(target, source) { 
  // 遍历源对象中的属性
  for (var property in source) {
    // 将源对象中的属性复制到目标对象中
    target[property] = source[property]; 
  }
  // 返回目标对象
  return target; 
};

“原来extend方法的实现就是对对象中的属性的一个复制过程呀。”小白惊讶地说。

“嗯,是这样,我们的这个extend方法是一个浅复制过程,他只能复制值类型的属性,对于引用类型的属性它无能为力。而在jquery等一些框架中实现了深复制,就是将源对象中的引用类型的属性再执行一遍extend方法而实现的。我们这里实现得比较简单,所以你测试也比较容易。”

于是小白写下如下测试代码。

var book = {
  name : 'JavaScript设计模式',
  alike : ['css', 'html', 'JavaScript']
}
var anotherBook = {
  color : 'blue'
}
extend(anotherBook, book);
console.log(anotherBook.name);   // JavaScript设计模式 
console.log(anotherBook.alike);   // ["css", "html", "JavaScript"] 
anotherBook.alike.push('ajax');
anotherBook.name = '设计模式';
console.log(anotherBook.name);   // 设计模式
console.log(anotherBook.alike);   // ["css", "html", "JavaScript", "ajax"] 
console.log(book.name);         // JavaScript设计模式 
console.log(book.alike);        // ["css", "html", "JavaScript", "ajax"]

“真的是这样。但是多继承呢?”

“很容易,既然上面的方法可以实现对一个对象属性的复制继承,那么如果我们传递多个对象呢?”

// 多继承 属性复制  
var mix = function() { 
  var i = 1,           // 从第二个参数起为被继承的对象
    len = arguments.length,   // 获取参数长度
    target = arguments[0],   // 第一个对象为目标对象
    arg;              // 缓存参数对象
  // 遍历被继承的对象
  for(; i < len; i++){
    // 缓存当前对象
    arg = arguments[i];
    // 遍历被继承对象中的属性
    for (var property in arg) {
      // 将被继承对象中的属性复制到目标对象中
      target[property] = arg[property]; 
    }
  }

  // 返回目标对象
  return target; 
};

“mix方法的作用就是将传入的多个对象的属性复制到源对象中,这样即可实现对多个对象的属性的继承。”

“这是实现方式真不错,可是使用的时候需要传入目标对象(第一个参数——需要继承的对象)。”

“当然你也可以将它绑定到原生对象Object上,这样所有的对象就可以拥有这个方法了。”

Object.prototype.mix = function(){
  var i = 0,           // 从第一个参数起为被继承的对象
    len = arguments.length,  // 获取参数长度
    arg;              // 缓存参数对象
  // 遍历被继承的对象
  for(; i < len; i++){
    // 缓存当前对象
    arg = arguments[i];
    // 遍历被继承对象中的属性
    for (var property in arg) {
      // 将被继承对象中的属性复制到目标对象中
      this[property] = arg[property]; 
    }
  }
}

“这样我们就可以在对象上直接调用了。如……”

otherBook.mix(book1, book2);
console.log(otherBook);  // Object {color: "blue", name: "JavaScript设计模式", mix: function, about: "一本JavaScript书"}

“在JavaScript中实现的多继承是如此的美妙。”

相关文章
|
JavaScript 前端开发
如何在 JavaScript 中使用 __proto__ 实现对象的继承?
使用`__proto__`实现对象继承时需要注意原型链的完整性和属性方法的正确继承,避免出现意外的行为和错误。同时,在现代JavaScript中,也可以使用`class`和`extends`关键字来实现更简洁和直观的继承语法,但理解基于`__proto__`的继承方式对于深入理解JavaScript的面向对象编程和原型链机制仍然具有重要意义。
|
设计模式 JavaScript 前端开发
JavaScript设计模式--访问者模式
【10月更文挑战第1天】
307 124
|
10月前
|
设计模式 JavaScript 算法
浅谈几种js设计模式
设计模式是软件开发中的宝贵工具,能够提高代码的可维护性和扩展性。通过单例模式、工厂模式、观察者模式和策略模式,我们可以解决不同场景下的实际问题,编写更加优雅和高效的代码。
311 8
|
JavaScript 前端开发 开发者
js实现继承怎么实现
【10月更文挑战第26天】每种方式都有其优缺点和适用场景,开发者可以根据具体的需求和项目情况选择合适的继承方式来实现代码的复用和扩展。
232 61
|
设计模式 前端开发 JavaScript
JavaScript设计模式及其在实战中的应用,涵盖单例、工厂、观察者、装饰器和策略模式
本文深入探讨了JavaScript设计模式及其在实战中的应用,涵盖单例、工厂、观察者、装饰器和策略模式,结合电商网站案例,展示了设计模式如何提升代码的可维护性、扩展性和可读性,强调了其在前端开发中的重要性。
188 2
|
JavaScript 前端开发
Javascript如何实现继承?
【10月更文挑战第24天】JavaScript 中实现继承的方式有很多种,每种方式都有其优缺点和适用场景。在实际开发中,我们需要根据具体的需求和情况选择合适的继承方式,以实现代码的复用和扩展。
135 11
|
自然语言处理 JavaScript 前端开发
一文梳理JavaScript中常见的七大继承方案
该文章系统地概述了JavaScript中七种常见的继承模式,包括原型链继承、构造函数继承、组合继承、原型式继承、寄生式继承、寄生组合继承等,并探讨了每种模式的实现方式及其优缺点。
一文梳理JavaScript中常见的七大继承方案
|
JavaScript 前端开发
如何使用原型链继承实现 JavaScript 继承?
【10月更文挑战第22天】使用原型链继承可以实现JavaScript中的继承关系,但需要注意其共享性、查找效率以及参数传递等问题,根据具体的应用场景合理地选择和使用继承方式,以满足代码的复用性和可维护性要求。
|
JavaScript 前端开发
js之class继承|27
js之class继承|27
|
JSON JavaScript 前端开发
js原型继承|26
js原型继承|26