JS:关于继承的困惑 [英] JS: Confusion about inheritance
问题描述
我通过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:
- 如何处理原型对象(在此示例中为
_n
)中的数据成员? -
Derived.prototype = new Base;
正在创建Base
的实例,并且该实例将始终保留在内存中(假定在Derived
中定义了全球空间).如果Base
类非常昂贵并且我不想要多余的对象怎么办?
- What to do with data members in prototype object (
_n
in this example)? Derived.prototype = new Base;
is creating an instance ofBase
and this will remain in memory always (assumingDerived
is defined in global space). What to do ifBase
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屋!