私はいつもJavaScriptのオブジェクト/クラスの継承に苦労しています。また、私が見つけることができるすべての例で重複したコードが好きではありません(オブジェクトの名前は数回書く必要があります)。
私が理解している限りでは、JavaScriptの適切な継承は次のようになります。
function Parent(v) {
console.log("Parent", v);
}
Parent.prototype.helloParent = function() {
console.log("hello parent");
}
function Child(v) {
Parent.call( this, "from child");
console.log("Child");
}
Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;
Child.prototype.helloChild = function() {
console.log("hello child");
}
c = new Child();
console.log(c instanceof Child);
c.helloParent();
c.helloChild();
この例では、 "Parent"オブジェクトを拡張するために、 "Child"を4回、 "Parent"を2回書く必要があります。両方とも一度だけ入力したいのですが ドライ.
のカスタム関数も定義したくありません。この継承のもの。そのような基本的な機能のためにユーザー関数が必要なのは、私にとっては奇妙に感じます(そして、この特定の継承関数が正確に何をしているのかわからないので、未知のコードを読みにくくなります)。
だから私はもっと単純なバージョンを見つけようとしました。しかし、私は何かを逃したかどうかわかりませんか?
function Parent(v) {
console.log("Parent", v);
this.helloParent = function() {
console.log("hello parent");
}
}
(Child = function(v) {
this.constructor("from child");
console.log("Child");
this.helloChild = function() {
console.log("hello child");
}
}).prototype = Parent.prototype;
c = new Child();
console.log(c instanceof Child);
c.helloParent();
c.helloChild();
これでいいですか、それとも重大な欠点がありますか?
編集:コメントに関しては、残念ながらそれはいくつかの深刻な欠点があるようです。少なくとも親オブジェクトの名前を複数回記述するために減らすための他の解決策はありますか?
回答:
回答№1は0JavaScriptの継承を簡単にするために、2つの非常に小さな関数を使用します。
function defclass(prototype) {
var constructor = prototype.constructor;
constructor.prototype = prototype;
return constructor;
}
function extend(constructor, keys) {
var prototype = Object.create(constructor.prototype);
for (var key in keys) prototype[key] = keys[key];
return defclass(prototype);
}
以下のように使用されます。
var Parent = defclass({
constructor: function (a) {
console.log("Parent", a);
},
helloParent: function () {
console.log("helloParent");
}
});
var Child = extend(Parent, {
constructor: function () {
Parent.call(this, "fromChild");
console.log("Child");
},
helloChild: function () {
console.log("helloChild");
}
});
最後に:
var child = new Child;
console.log(child instanceof Child);
child.helloParent();
child.helloChild();
すべてを一緒に入れて:
function defclass(prototype) {
var constructor = prototype.constructor;
constructor.prototype = prototype;
return constructor;
}
function extend(constructor, keys) {
var prototype = Object.create(constructor.prototype);
for (var key in keys) prototype[key] = keys[key];
return defclass(prototype);
}
var Parent = defclass({
constructor: function (a) {
console.log("Parent", a);
},
helloParent: function () {
console.log("helloParent");
}
});
var Child = extend(Parent, {
constructor: function () {
Parent.call(this, "fromChild");
console.log("Child");
},
helloChild: function () {
console.log("helloChild");
}
});
var child = new Child;
console.log(child instanceof Child);
child.helloParent();
child.helloChild();
希望が役立ちます。
回答№2の場合は0
JavaScriptのoopは醜いです。 (少なくともクラスをサポートし、キーワードを実装するES6まで)しかしES6でさえ多重継承をサポートしないでしょう。私が書いた 小さなクラスライブラリ(githubから入手可能) クラスと継承の作成が開発と保守の両方をはるかに容易にするJavaScriptのため。たとえばクラスを作成するには、これを実行するだけです。
ds.make.class({
type: "a",
constructor: function (x) { this.val = x; },
mul: function (s) {
this.val *= s;
return this;
}
});
// now to inherit class a just do this...
ds.make.class({
type: "b",
inherits: a,
constructor: function (x) { this.val = x; },
sub: function (s) {
this.val -= s;
return this;
}
});
var o = new b(5);
var output = o.mul(3).sub(5).val; // output = 10