JS:关于继承的困惑

tas*_*oor 6 javascript

我通过C++,Java等语言熟悉OOP概念.现在我正在尝试学习JavaScript作为一种爱好,主要是因为对WebGL的兴趣.但我在基于原型的继承方面遇到了麻烦.

假设我有一个基类接受构造函数中的参数.我需要扩展这一点.我这样做的方式如下所示.

function Base(n) {
    this._n = n;
}

Base.prototype.print = function() {
    console.log(this._n);
}

function Derived(n) {
    Base.call(this, n);
}

Derived.prototype = new Base;
Derived.prototype.constructor = Derived;
Run Code Online (Sandbox Code Playgroud)

现在这就是我的理解:单个Base对象作为原型Derived.因此,所有实例都Derived将从此Base对象继承属性,例如print方法.当我调用new Derived(10)然后创建一个新对象时,Derived在这个新创建的对象的上下文中调用函数,即this指向新创建的对象,并Base从函数调用函数Derived,然后_n创建并赋值10.因此,如果我创建5个Derived对象,所有这些对象都有自己的_n属性.到目前为止,这没关系.

但我不喜欢这句话:

Derived.prototype = new Base;
Run Code Online (Sandbox Code Playgroud)

函数Base需要一个参数但我在这里没有传递任何东西.这里没有传递参数的意义,因为这个对象将作为原型Derived.我不需要_n这个原型对象的任何值.但是如果函数Base依赖于参数呢?比如说,Base加载资源并将路径作为参数传递.该怎么办?

总结一下,我的问题是:

  1. 如何处理原型对象中的数据成员(_n在此示例中)?
  2. Derived.prototype = new Base;正在创建一个实例,Base并且它将始终保留在内存中(假设Derived在全局空间中定义).如果Base课程费用很高而且我不想要额外的物品怎么办?

Ray*_*nos 1

但我不喜欢这一行:

Derived.prototype = new Base;

然后将其替换为

Derived.prototype = Object.create(Base.prototype);

SeeObject.create只是返回一个新对象,该对象[[Prototype]]是您给它的第一个参数。

它基本上是说Derived继承自Base但不要调用那个该死的构造函数!

如何处理原型对象中的数据成员(本例中为 _n)?

当您的链接原型不调用构造函数时!我写了一篇关于此的JS OO 第 3 部分文章。

它基本上是说,当您创建对象时,您会实例化并初始化。

// instantiate
var o = Object.create(Base.prototype);
// o now inherits all of Bases methods because o.[[Prototype]] === Base.prototype
// o also inherits the constructor function (Base.prototype.constructor === Base)
// initialize
o.constructor(10);
Run Code Online (Sandbox Code Playgroud)

现在当然new X两者都做到了。以下是 new 功能的概述

var new = function (constructor, ...args) {
  var instance = Object.create(constructor.prototype);
  instance.constructor(...args);
  return instance;
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,您不希望这样做new,因为您不希望调用该构造函数(您不需要初始化 Derived.prototype)。

Derived.prototype = 新的 Base; 正在创建 Base 的实例,它将始终保留在内存中(假设 Derived 是在全局空间中定义的)。如果基类非常昂贵并且我不想要额外的对象该怎么办?

这种担忧Object.create是无效的。实例化一个对象很便宜。它只是生成一个新的事物对象,其内部[[Prototype]]属性是指向您传入的原型的指针。

唯一可能昂贵的是构造函数,并且您不调用构造函数。

次要免责声明:

Object.createES5和一些旧版浏览器(主要是IE8)不支持。然而,有一个叫做ES5-shim 的可爱东西可以修复这些浏览器并使它们表现得像 ES5。