JavaScriptで閉鎖定義の「クラス」を「拡張」できますか?
-
01-10-2019 - |
質問
javascriptの「クラス」がそうであると定義されています:
var Welcomer = function(name) {
var pName = name;
var pMessage = function() {
return "Hi, " + pName + "!";
};
return {
sayHi: function() {
alert(pMessage());
}
};
};
new Welcomer('Sue').sayHi();
「サブクラス」をする方法はありますか Welcomer
パブリックメソッドを再定義し、プライベートな方法と変数にアクセスできるような方法で?以下は、公共の方法にアクセスできますが、プライベートな方法ではありません。
var UnhappyWelcomer = function(name) {
var pSadMessage = function() {
// won't work, b/c I don't have access to pMessage
return pMessage() + " Miserable day, innit?";
};
return {
sayHi: function() {
alert(pSadMessage());
}
};
};
UnhappyWelcomer.prototype = Welcomer(); // failed attempt at inheritance
new UnhappyWelcomer().sayHi();
解決
あなたの質問に対する簡単な答えはです いいえ.
それらにアクセスするために何もできません var
あなたの関数が同じ範囲にある場合、またはあなたが何らかの形で情報を「公開」しない限り、定義されたもの(それを返すか、それを設定することによって this
).
ただし、元の関数を編集するためにアクセスできる場合は、これらの関数を拡張機能に「渡す」ことができるように物事を書き換えることができ、オブジェクトの「保護された」範囲を変更できます。次のコードは、私が提案しているものについて良い考えを与えるはずです。
var Welcomer = function(name) {
var _protected = {
name: name,
message: function() {
return "Hi, " + _protected.name + "!";
}
};
return {
extendWith: function(extender) {
extender.call(this, _protected);
return this;
},
sayHi: function() {
alert(_protected.message());
}
};
};
var UnhappyWelcomer = function(name) {
var self = Welcomer(name).extendWith(function(_protected) {
_protected.sadMessage = function() {
return _protected.message() + " Miserable day, innit?";
};
// extending the public while still having scope to _protected...
this.sayHi = function() {
alert(_protected.sadMessage());
};
});
return self;
};
UnhappyWelcomer('bob').sayHi();
他のヒント
その「クラス」パターンは「クラス」パターンではなく、 モジュールパターン. 。それは、それを作成した関数と関係がないオブジェクトを返します。返されたオブジェクトは、それを作成した関数のインスタンスではありません。
「new class()」を呼び出すと、その関数のインスタンスが作成されますが、別のオブジェクトも返します。それ以上の操作は、実際にはインスタンスではなく、返されたオブジェクト上にあります。
継承を使用するには、プロトタイプの継承を適切に使用する必要があります。読むことをお勧めします。
- プロトタイプの継承 ダグラス・クロックフォード
- JavaScriptのプライベートメンバー ダグラス・クロックフォード
- JavaScriptのプロトタイプと継承 スコット・アレンによる(注: 原子 標準ではありません)
参考文献:
読んでいる資料を残して申し訳ありませんが、私にはあなたが可能性を模索しているようです。これらの記事は、この問題についてより深い洞察を与えます。
この問題についてもっと知ると、プライベートメンバーを完全に無視し、_プレフィックスを使用して、他のすべての人と同じように公開メンバーにするだけです。
継承が本当に必要な場合は、非常に役立つライブラリがいくつかあります。 1つのオプションはです tat.js, 、とにかくある時点で実際にJavaScriptの標準的な部分になる可能性があります。それがあなたのボートを浮かせない場合、jQueryやプロトタイプのような図書館には相続のヘルパーがあります。
最小/sscratchアプローチを使用したい場合は、すべてにプロトタイプモデルを使用することを強くお勧めします。あなたの例では、あなたが持っているパターンよりも大きなパフォーマンスが増加します。
あなたの質問にもっと直接対処するために、いいえ。 「クラス」を設計すると、プライベート機能が依存していない場合が簡単な時間があります。