JS:关于继承的困惑 [英] JS: Confusion about inheritance

查看:54
本文介绍了JS:关于继承的困惑的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am familiar with OOP concepts through the languages like C++, Java. Right now I am trying to learn JavaScript as a hobby, mainly due to the interest in WebGL. But I am having troubles with prototype based inheritance.

假设我有一个基类,该基类在构造函数中接受参数.我需要扩展它.我的操作方式如下所示.

Let's say I have a base class which accepts a parameter in constructor. And I need to extend this. The way I am doing this is shown below.

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;

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

Now this is what I understand: A single Base object is serving as the prototype of Derived. So all instances of Derived will inherit properties from this Base object, e.g. the print method. When I call new Derived(10) then a new object is created, function Derived is called in the context of this newly created object, i.e. this points to newly created object, and function Base is called from function Derived, and then _n is created and assigned the value 10. So if I create 5 Derived objects, all of them will have their own _n property. So far this is okay.

但是我不喜欢这条线:

Derived.prototype = new Base;

函数 Base 需要一个参数,但是我在这里没有传递任何内容.这里没有传递参数的意义,因为此对象将充当 Derived 的原型.而且我不需要此原型对象的任何 _n 值.但是,如果函数 Base 取决于参数呢?假设 Base 加载资源,并且路径作为参数传递.那该怎么办呢?

Function Base expects an argument but I am passing nothing here. There is no point of passing a parameter here as this object will act as prototype of Derived. And I don't need any value of _n for this prototype object. But what if the function Base depends on the argument? Say, Base loads a resource and the path is passed as parameter. What to do then?

总而言之,我的问题是:

To summarize, my questions are:

  1. 如何处理原型对象(在此示例中为 _n )中的数据成员?
  2. Derived.prototype = new Base; 正在创建 Base 的实例,并且该实例将始终保留在内存中(假定在 Derived 中定义了全球空间).如果 Base 类非常昂贵并且我不想要多余的对象怎么办?
  1. What to do with data members in prototype object (_n in this example)?
  2. Derived.prototype = new Base; is creating an instance of Base and this will remain in memory always (assuming Derived is defined in global space). What to do if Base class is very costly and I don't want an extra object?

推荐答案

但是我不喜欢这条线:

But I don't like this line:

Derived.prototype = new Base;

然后将其替换为

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

请参见 Object.create 只是返回一个新对象,该对象的 [[Prototype]] 是您为其赋予的第一个参数.

See Object.create simply returns a new object whose [[Prototype]] is the first parameter you give it.

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

It's basically saying Derived inherits from Base but don't call that damned constructor!

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

What to do with data members in prototype object (_n in this example)?

当链接原型不调用构造函数时!我写了 JS OO第3部分文章,内容涉及这个.

When your chaining prototypes don't call the constructor! I wrote an JS OO part 3 article about this.

它基本上说当您创建对象时,您要实例化和初始化.

It basically says that when you create objects you instantiate and initialize.

// 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);

现在当然 new X 都可以.这是新功能的概观

Now of course new X does both. Here's an over view of what new does

var new = function (constructor, ...args) {
  var instance = Object.create(constructor.prototype);
  instance.constructor(...args);
  return instance;
}

如您所见,您不想使用 new ,因为您不希望调用该构造函数(不需要初始化Derived.prototype).

As you can see you don't want new because you don't want that constructor to be called (You don't need to initialize Derived.prototype).

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

Derived.prototype = new Base; is creating an instance of Base and this will remain in memory always (assuming Derived is defined in global space). What to do if Base class is very costly and I don't want an extra object?

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

This concern with Object.create is void. instantiating an object is cheap. It just generates a new thing object whose internal [[Prototype]] property is a pointer to the prototype you pass in.

唯一昂贵的东西是构造函数,而您不调用该构造函数.

The only thing that can be expensive is the constructor, and you don't call the constructor.

次要免责声明:

Object.create 是ES5,某些旧版浏览器(主要是IE8)不支持.但是,有一个可爱的东西称为 ES5-shim ,它可以修复这些浏览器并使它们的行为类似于ES5.

Object.create is ES5 and some legacy browsers (mainly IE8) don't support. However there's this lovely thing called the ES5-shim that fixes these browsers and makes them behave like ES5.

这篇关于JS:关于继承的困惑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆