《JavaScript设计模式》——2.4 老师不止一位——多继承-阿里云开发者社区

开发者社区> 开发与运维> 正文

《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中实现的多继承是如此的美妙。”

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享:
开发与运维
使用钉钉扫一扫加入圈子
+ 订阅

集结各类场景实战经验,助你开发运维畅行无忧

其他文章