JavaScript如何继承父对象(或称“父类”)

众所周知,JavaScript是基于原型的面向对象,没有类的概念。因此在继承父对象上,与Ruby/Python等基于类的语言在继承父类上有显著区别。

原型继承方式不唯一,可单继承也可多继承,较为灵活。在此有3种比较简单的单继承方式,3种方法都是JavaScript原生提供的。

多继承及更多相关 API 参考:MDN – Object.create

No.1 Object.create

请看下面示例程序:

// No.1
let Name = (function(undefined) {
  function Name(firstname, lastname) {
    this.name = `${firstname} ${lastname}`;
  };

  Name.prototype.setName = function(firstname, lastname) {
    this.name = `${firstname} ${lastname}`;
  } 
  
  return Name;
})(undefined);

// Subclass
let NameUpgraded = (function(undefined) {
  function NameUpgraded(firstname, lastname) {
    Name.call(this, firstname, lastname);                 // Call the parent constructor
  }
  NameUpgraded.prototype = Object.create(Name.prototype); // Copy prototype(s) of parent obj
  NameUpgraded.prototype.constructor = NameUpgraded;      // Set the constructor of nameUpgraded
  // Or Node.js
  // util.inherits(NameUpgraded, Name);

  NameUpgraded.prototype.getName = function() {
    return this.name;
  }
  
  return NameUpgraded;
})(undefined);

基于原型的继承本质上就是继承父对象的原型链。因此,上述示例程序的基对象为Name,其具有一个原型方法setName()。

子对象NameUpgraded为了继承Name,步骤如下:

  1. 首先执行“Name.call(this, firstname, lastname)”调用Name的构造函数;
  2. 然后利用Object.create()方法继承Name的原型链;
  3. 最后再指明NameUpgraded的构造函数,即NameUpgraded。

再为NameUpgraded添加一个名为getName的原型方法。

在Nightly 57中展开NameUpgraded后如下图:

JavaScript-ObjectCreate
JavaScript原型继承示例

No.2 Class(ES6)

这个较为简单,下面为示例程序,其语法风格类似Java。

// No.2
class Name {
  constructor(arguments) {
    // some code
  }
}

// Or anonymous class
// const Name = class {
//  constructor(arguments) {
//    // some code
//  }
//}

class NameUpgraded extends Name {
  constructor(arguments) {
    super(arguments);
    // some code
  }
}

不过这里要说明的是,class关键字仅仅是JavaScript的语法糖,本质上class声明的东西仍然是function。

No.3 Object.assign

严格意义上说,这个不算继承,是JavaScript的Mixin,不过可以达到继承的效果。

// No.3
const Name = function (obj) {
  this.name = '';

  return Object.assign({}, obj, {
    setName(name) {
      return this.name = name;
    }
  });
};

const NameUpgraded = function (obj) {
  this.name = '';

  return Object.assign({}, obj, {
    getName() {
      return this.name;
    }
  });
};

Joe = Name(NameUpgraded({}));
me.setName('Joe');
me.getName();             // -> "Joe"

利用Object.assign可以方便地将两个对象连接起来,而assign的第一个参数设置为空对象“{}”,是因为JavaScript一切皆是引用,第一个参数设置为空对象可以创建一个新对象,而不是引用原来的对象。因此通过mixin也可以达到对象继承的效果。

当然,JavaScript里面的继承方式很多,不局限于这里的几种方式,欢迎广大网友补充,提供你们的宝贵经验和知识。

参考:

  1. MDN – Object.create

作者: YanWen

Web 开发者

发表评论

Fill in your details below or click an icon to log in:

WordPress.com 徽标

You are commenting using your WordPress.com account. Log Out /  更改 )

Google photo

You are commenting using your Google account. Log Out /  更改 )

Twitter picture

You are commenting using your Twitter account. Log Out /  更改 )

Facebook photo

You are commenting using your Facebook account. Log Out /  更改 )

Connecting to %s