我最近通过编写一些gnome shell扩展来学习javascript,因此我对Javascript的理解已经被我在gnome-shell javascript源中观察到的例子所塑造.我有一种感觉,我一直在理解错误的课程,只是想要一些澄清.
我已经编写了一些自己的子类,并且在每种情况下我只是通过遵循gnome-shell javascript源代码中的类似代码来定义它们:
Subclass = function() {
this._init.apply(this,arguments);
}
Subclass.prototype = {
__proto__: Superclass.prototype,
_init: function() {
Superclass.prototype._init.call(this);
},
// add other methods of Subclass here.
}
Run Code Online (Sandbox Code Playgroud)
到目前为止,我认为这是制作课程的标准方式,Subclass
基本上是Superclass
额外的.我假设每个对象都有一个_init
方法.
我最近尝试应用相同的方法来创建a的子类Clutter.Actor
(重要的是它不是GNOME-shell定义的类),并且意识到上面的子类化对象的方式不是标准.首先,并非每个班级都有_init
我所假设的功能; 这只是GNOME-shell在他们的javascript类中完成的事情.
所以,我的问题是:
Subclass.prototype = new Superclass()
而不是做Subclass.prototype = { __proto__:Superclass.prototype, define_prototype_methods_here }
方法,但我的想法是,如果gnome-shell一直使用它,必须有一些方法吗?Superclass.prototype._init.call(this)
同在Subclass._init
,以确保在Subclass.prototype
得到所有Superclass
(我在我的定义中添加的方法/属性Subclass.prototype
),如果Superclass
没有_init
函数(即它是否有一些我调用的等效构造函数)?我真的很困惑这一切所以请原谅我,如果我的问题没有多大意义; 这是因为我的误解和困惑的程度!
编辑:澄清: - 我知道__proto__
不推荐,因为它是非标准的,但我的代码永远不会在浏览器中运行 - 它只会运行GNOME javascript(基本上是Mozilla javascript引擎),所以我不需要担心交叉兼容性.
如前所述,不要使用__proto__
.这是一个非标准的财产. (它现在已经在浏览器中标准化了JavaScript.仍然不使用它.)但是
Subclass.prototype = new Superclass(); // Don't do this
Run Code Online (Sandbox Code Playgroud)
也不是一个非常好的方法.如果Superclass
需要参数怎么办?
你有更好的选择.
class
为您处理所有这些管道; 完整的例子:
class Superclass {
constructor(superProperty) {
this.superProperty = superProperty;
}
method() {
console.log("Superclass's method says: " + this.superProperty);
}
}
class Subclass extends Superclass {
constructor(superProperty, subProperty) {
super(superProperty);
this.subProperty = subProperty;
}
method() {
super.method(); // Optional, do it if you want super's logic done
console.log("Subclass's method says: " + this.subProperty);
}
}
let o = new Subclass("foo", "bar");
console.log("superProperty", o.superProperty);
console.log("subProperty", o.subProperty);
console.log("method():");
o.method();
Run Code Online (Sandbox Code Playgroud)
让我们Subclass.prototype
继承Superclass.prototype
.这可以通过例如ES5来完成Object.create
:
Subclass.prototype = Object.create(Superclass.prototype);
Subclass.prototype.constructor = Subclass;
Run Code Online (Sandbox Code Playgroud)
然后在Subclass
,您Superclass
通过this
引用该对象进行调用,以便它有机会初始化:
function Subclass() {
Superclass.call(this); // Pass along any args needed
}
Run Code Online (Sandbox Code Playgroud)
完整示例:
function Superclass(superProperty) {
this.superProperty = superProperty;
}
Superclass.prototype.method = function() {
console.log("Superclass's method says: " + this.superProperty);
};
function Subclass(superProperty, subProperty) {
Superclass.call(this, superProperty);
this.subProperty = subProperty;
}
Subclass.prototype = Object.create(Superclass.prototype);
Subclass.prototype.constructor = Subclass;
Subclass.prototype.method = function() {
Superclass.prototype.method.call(this); // Optional, do it if you want super's logic done
console.log("Subclass's method says: " + this.subProperty);
};
var o = new Subclass("foo", "bar");
console.log("superProperty", o.superProperty);
console.log("subProperty", o.subProperty);
console.log("method():");
o.method();
Run Code Online (Sandbox Code Playgroud)
ES3和更早版本没有Object.create
,但你可以很容易地编写一个为你设置原型的函数:
function objectCreate(proto) {
var ctor = function() { };
ctor.prototype = proto;
return new ctor;
}
Run Code Online (Sandbox Code Playgroud)
(注意:你可以Object.create
通过创建一个只需要一个参数的一半来进行半垫片,但是多参数版本Object.create
不能被填充,所以如果它也使用的话,它会给页面上的其他代码提供错误的想法Object.create
.)
然后你做我们的ES5例子:
完整示例:
function objectCreate(proto) {
var ctor = function() { };
ctor.prototype = proto;
return new ctor;
}
function Superclass(superProperty) {
this.superProperty = superProperty;
}
Superclass.prototype.method = function() {
console.log("Superclass's method says: " + this.superProperty);
};
function Subclass(superProperty, subProperty) {
Superclass.call(this, superProperty);
this.subProperty = subProperty;
}
Subclass.prototype = objectCreate(Superclass.prototype);
Subclass.prototype.constructor = Subclass;
Subclass.prototype.method = function() {
Superclass.prototype.method.call(this); // Optional, do it if you want super's logic done
console.log("Subclass's method says: " + this.subProperty);
};
var o = new Subclass("foo", "bar");
console.log("superProperty", o.superProperty);
console.log("subProperty", o.subProperty);
console.log("method():");
o.method();
Run Code Online (Sandbox Code Playgroud)