JavaScriptのモジュール化:パッケージ(クローズド)、継承(プロトタイプ)紹介
7185 ワード
JavaScriptは持ち前のくだけた姿だが、ブラウザでできることが多くなるにつれて、この言語はますます正気を引き締めている.複雑な論理の下で、JavaScriptはモジュール化される必要があり、モジュールはパッケージ化され、外部からの呼び出しのためのインターフェースだけを残しておく必要がある.クローズドはJavaScriptでモジュールパッケージを実現するための鍵であり、初心者には理解しにくいポイントでもあります.最初は、私も迷っていました.今、私はこの概念に対して、より深い理解ができたと自信を持っています.理解を容易にするために、比較的簡単なオブジェクトをパッケージ化しようとする.
私たちはカウンタオブジェクトのtickerをページ上で維持しようとします.このオブジェクトは数値nを維持します.ユーザの操作により、一度のカウントを増加することができますが、nを減少させることはできません.そして、時々この数値を調べます.
ポータルが大きく開くJSONスタイルのモジュール化
一つのドアを大きく開く方法は、
実は、このような「門戸が大きく開く」タイプのモジュール化方式は、プログラムではなくJSONスタイルのデータを組織するためによく使われます.例えば、以下のJSONオブジェクトをtickerのある関数に伝えて、tickerが100から数え始め、毎回2に進むことを決めます.
しかし、まだ問題があります.つまり、tickはどうやって呼び出しますか?tickerの役割域もティックを隠しています.解決方法は2つあります.
•1)必要な呼び出し方法を戻り値として、nをインクリメントする方法をticker()の戻り値とします.2)外部作用領域の変数を設定し、私たちがticker()にgetNを設定するようにします.
このセクションの最初のコードの中で、ticker()メソッドが実行された後、nとtick()は破壊されました.次の関数が呼び出された時に作成します.ただし、第二のセグメントコードでは、ticker()が実行された後、nは破壊されない.tick()とgetN()がそれにアクセスしたり変更したりする可能性があるので、ブラウザはnを維持する責任がある.「クローズド」に対する理解は、nが関数の役割領域内にあることを保証するために、関数の実行が終了しても維持が必要であり、他の方法でアクセスされる可能性のある変数が破壊されない仕組みであるということです.
でも、やはりおかしいと思います.もし私が同じ機能を持つ2つの相手のticker 1とticker 2を維持したいなら、どうすればいいですか?tickerは一つしかないので、もう一回書いてもいいですか?
new演算子とコンストラクタは、new演算子を介して関数を呼び出すと、新しいオブジェクトを作成し、この関数を呼び出すためにオブジェクトを使用します.私の理解では、下のコードの中でt 1とt 2の構造過程は同じです.
プロトタイプと上のTICKERを引き継ぐのはまだ欠陥があります.参照してください.new演算子を使用するたびに、TICKER()を呼び出します.新しいオブジェクトを生成し、新しい関数を作成してこの新しいオブジェクトに結びつけます.新しいオブジェクトを構築するごとに、ブラウザは空間を開きます.tick()自体とtick()の変数を格納します.これは私たちが望むものではありません.私たちはticker 1.tickとticker 2.tickが同じ関数オブジェクトを指すことを期待します.
これは原型を導入する必要があります.
JavaScriptでは、Objectオブジェクトを除いて、他のオブジェクトにプロトタイプの属性があります.この属性は他のオブジェクトを指します.この「もう一つのオブジェクト」はまだ原型のオブジェクトがあり、原型のチェーンが形成され、最終的にはObjectオブジェクトを指します.あるオブジェクトにある方法を呼び出した時、このオブジェクトに指定された方法がないことが判明したら、Objectオブジェクトまでプロトタイプチェーンで前回検索します.
関数もオブジェクトですので、関数にもプロトタイプのオブジェクトがあります.関数が宣言されると、新しいオブジェクトが生成されます.このオブジェクトのprototype属性はObjectオブジェクトを指し、さらにこのオブジェクトのconstruct属性は関数オブジェクトを指します.
構造関数によって構築された新しいオブジェクトは,そのプロトタイプが構造関数のプロトタイプオブジェクトに向けられている.したがって、構造関数のプロトタイプオブジェクトに関数を追加することができます.これらの関数は、ticker 1やticker 2に依存するのではなく、TICKERに依存します.
そうするかもしれません.
したがって、オブジェクトのパッケージ性を維持するために、データの動作をできるだけ小さいセル関数に結合することを提案します.構造関数では、インスタンスに依存すると定義されています.
最後に相続について話をします.実際には、プロトタイプに関数を定義するときに、私たちはすでに引き継ぎに使いました.JavaScriptの中の継承はC++の中のものよりもっと…えっと、簡単ですか?それとも粗末です.C++の中で、アニマル類の表示動物を定義して、バード類の継承アニマル類を定義することができますが、このような継承ではないことを検討したいです.検討したいのですが、C++の中将では、アニマルクラスを定義し、マイアニマルオブジェクトを具体化しました.はい、これはC++で実用化されていますが、JavaScriptでは継承として扱われています.
JavaScriptはクラスをサポートしていません.ブラウザにはどのようなオブジェクトがありますか?私達の例では、TICKER()は関数オブジェクトであり、その赋値(TICKER=1)を削除してもいいですが、現在はticker 1とticker 2のオブジェクトがnew演算子で呼び出されているだけに、TICKER()は構造関数として機能します.TICKER.prototypeも対象として機能します.
以上は私が知っているJavaScriptモジュール化の方法です.もしあなたも初心者なら、あなたのために役に立つと思います.間違ったところがあれば、ご指摘をお願いします.
一葉斎主出典:www.cnblogs.com/yiyezhai
私たちはカウンタオブジェクトのtickerをページ上で維持しようとします.このオブジェクトは数値nを維持します.ユーザの操作により、一度のカウントを増加することができますが、nを減少させることはできません.そして、時々この数値を調べます.
ポータルが大きく開くJSONスタイルのモジュール化
一つのドアを大きく開く方法は、
var ticker = {
n:0,
tick:function(){
this.n++;
},
};
このように書くのは自然で、しかも確実に有効です.私達は一回のカウントを増やす必要があります.ticker.tick()メソッドを呼び出して、検索回数が必要な時、ticker.n変数にアクセスします.しかし、その欠点も明白である.モジュールの使用者は、例えば、ticker.n--またはticker.n=-1を呼び出すなど、nを自由に変えることができる.私たちはチケットをカプセル化していません.nとtickは見たところtickerの「メンバー」に見えますが、それらのアクセス性はtickerと同じで、全体的です.パッケージ性では、このようなモジュール化の仕方は以下のようなよりもおかしいです.少ししかないです.
var ticker = {};
var tickerN = 0;
var tickerTick = function(){
tickerN++;
}
tickerTick();
注意すべきなのは、tickの中で、私が訪問したのはthis.n――これはnがtickerのメンバーであるからではなく、tickを呼んだのがtickerだからです.実はここでticker.nと書いたほうがいいです.tickを呼んだのはtickerではなく、他のものです.例えば:
var func = ticker.tick;
func();
このとき、tickを呼び出すのはwindowですが、関数実行時はwindow.nにアクセスしようとしてエラーが発生します.実は、このような「門戸が大きく開く」タイプのモジュール化方式は、プログラムではなくJSONスタイルのデータを組織するためによく使われます.例えば、以下のJSONオブジェクトをtickerのある関数に伝えて、tickerが100から数え始め、毎回2に進むことを決めます.
var config = {
nStart:100,
step:2
}
作用するドメインチェーンとクローズドは下記のコードを見て、私達はすでにインプットされたconfigでtickerをカスタマイズすることを実現しました.
function ticker(config){
var n = config.nStart;
function tick(){
n += config.step;
}
}
console.log(ticker.n); // ->undefined
どうやって相手から関数になったのかと疑問に思うかもしれません.これはJavaScriptには関数だけが機能領域を持っていますので、関数の体外から関数内部の変数にアクセスできません.ticker()外訪問ticker.nはundefinedを獲得しますが、tick()内訪問nは問題ありません.tick()からticker()にかけて大域に行くというのがJavaScriptの「作用域チェーン」です.しかし、まだ問題があります.つまり、tickはどうやって呼び出しますか?tickerの役割域もティックを隠しています.解決方法は2つあります.
•1)必要な呼び出し方法を戻り値として、nをインクリメントする方法をticker()の戻り値とします.2)外部作用領域の変数を設定し、私たちがticker()にgetNを設定するようにします.
var getN;
function ticker(config){
var n = config.nStart;
getN = function(){
return n;
};
return function(){
n += config.step;
};
}
var tick = ticker({nStart:100,step:2});
tick();
console.log(getN()); // ->102
参照してください.このとき変数nは「クローズド」の中にあり、外部から直接アクセスできないが、二つの方法で観察または操作できます.このセクションの最初のコードの中で、ticker()メソッドが実行された後、nとtick()は破壊されました.次の関数が呼び出された時に作成します.ただし、第二のセグメントコードでは、ticker()が実行された後、nは破壊されない.tick()とgetN()がそれにアクセスしたり変更したりする可能性があるので、ブラウザはnを維持する責任がある.「クローズド」に対する理解は、nが関数の役割領域内にあることを保証するために、関数の実行が終了しても維持が必要であり、他の方法でアクセスされる可能性のある変数が破壊されない仕組みであるということです.
でも、やはりおかしいと思います.もし私が同じ機能を持つ2つの相手のticker 1とticker 2を維持したいなら、どうすればいいですか?tickerは一つしかないので、もう一回書いてもいいですか?
new演算子とコンストラクタは、new演算子を介して関数を呼び出すと、新しいオブジェクトを作成し、この関数を呼び出すためにオブジェクトを使用します.私の理解では、下のコードの中でt 1とt 2の構造過程は同じです.
function myClass(){}
var t1 = new myClass();
var t2 = {};
t2.func = myClass;
t2.func();
t2.func = undefined;
t 1とt 2は新しい構造の対象です.myClassは構造関数です.似ています.tickerは書き換えられます.
function TICKER(config){
var n = config.nStart;
this.getN = function(){
return n;
};
this.tick = function(){
n += config.step;
}
}
var ticker1 = new TICKER({nStart:100,step:2});
ticker1.tick();
console.log(ticker1.getN()); // ->102
var ticker2 = new TICKER({nStart:20,step:3});
ticker2.tick();
ticker2.tick();
console.log(ticker2.getN()); // ->26
一般的には、構造関数は大文字で使用されます.なお、TICKER()は、純粋なオブジェクトではなく関数です.(「純粋」というのは、関数が実際に対象であるため、TICKER()は関数オブジェクトです.プロトタイプと上のTICKERを引き継ぐのはまだ欠陥があります.参照してください.new演算子を使用するたびに、TICKER()を呼び出します.新しいオブジェクトを生成し、新しい関数を作成してこの新しいオブジェクトに結びつけます.新しいオブジェクトを構築するごとに、ブラウザは空間を開きます.tick()自体とtick()の変数を格納します.これは私たちが望むものではありません.私たちはticker 1.tickとticker 2.tickが同じ関数オブジェクトを指すことを期待します.
これは原型を導入する必要があります.
JavaScriptでは、Objectオブジェクトを除いて、他のオブジェクトにプロトタイプの属性があります.この属性は他のオブジェクトを指します.この「もう一つのオブジェクト」はまだ原型のオブジェクトがあり、原型のチェーンが形成され、最終的にはObjectオブジェクトを指します.あるオブジェクトにある方法を呼び出した時、このオブジェクトに指定された方法がないことが判明したら、Objectオブジェクトまでプロトタイプチェーンで前回検索します.
関数もオブジェクトですので、関数にもプロトタイプのオブジェクトがあります.関数が宣言されると、新しいオブジェクトが生成されます.このオブジェクトのprototype属性はObjectオブジェクトを指し、さらにこのオブジェクトのconstruct属性は関数オブジェクトを指します.
構造関数によって構築された新しいオブジェクトは,そのプロトタイプが構造関数のプロトタイプオブジェクトに向けられている.したがって、構造関数のプロトタイプオブジェクトに関数を追加することができます.これらの関数は、ticker 1やticker 2に依存するのではなく、TICKERに依存します.
そうするかもしれません.
function TICKER(config){
var n = config.nStart;
}
TICKER.prototype.getN = function{
// attention : invalid implementation
return n;
};
TICKER.prototype.tick = function{
// attention : invalid implementation
n += config.step;
};
これは無効な実現です.プロトタイプオブジェクトの方法では、クローズドの内容、つまり変数nにアクセスできません.TICK()メソッドが実行されてからnにアクセスできなくなり、ブラウザがnを破壊します.クローズド・パケット中のコンテンツにアクセスするためには、オブジェクトは、インスタンスに依存するいくつかの簡潔な方法が必要であり、クローズド・パケット中のコンテンツにアクセスし、その後、そのprototype上で複雑な公有方法を定義して論理を実装する.実際には、例のtickの方法はもう十分簡潔です.私たちはそれをTICKERに戻しましょう.以下では、使用者がtick()を呼び出す回数を指定することができる複雑な方法tickTimesを実装する.
function TICKER(config){
var n = config.nStart;
this.getN = function(){
return n;
};
this.tick = function(){
n += config.step;
};
}
TICKER.prototype.tickTimes = function(n){
while(n>0){
this.tick();
n--;
}
};
var ticker1 = new TICKER({nStart:100,step:2});
ticker1.tick();
console.log(ticker1.getN()); // ->102
var ticker2 = new TICKER({nStart:20,step:3});
ticker2.tickTimes(2);
console.log(ticker2.getN()); // ->26
このTICKERがいいです.これはnをカプセル化していて、オブジェクトの外部から直接に変えることができません.複雑な関数tickTimes()はプロトタイプに定義されています.この関数はインスタンスの小関数を呼び出して、オブジェクト中のデータを操作します.したがって、オブジェクトのパッケージ性を維持するために、データの動作をできるだけ小さいセル関数に結合することを提案します.構造関数では、インスタンスに依存すると定義されています.
最後に相続について話をします.実際には、プロトタイプに関数を定義するときに、私たちはすでに引き継ぎに使いました.JavaScriptの中の継承はC++の中のものよりもっと…えっと、簡単ですか?それとも粗末です.C++の中で、アニマル類の表示動物を定義して、バード類の継承アニマル類を定義することができますが、このような継承ではないことを検討したいです.検討したいのですが、C++の中将では、アニマルクラスを定義し、マイアニマルオブジェクトを具体化しました.はい、これはC++で実用化されていますが、JavaScriptでは継承として扱われています.
JavaScriptはクラスをサポートしていません.ブラウザにはどのようなオブジェクトがありますか?私達の例では、TICKER()は関数オブジェクトであり、その赋値(TICKER=1)を削除してもいいですが、現在はticker 1とticker 2のオブジェクトがnew演算子で呼び出されているだけに、TICKER()は構造関数として機能します.TICKER.prototypeも対象として機能します.
以上は私が知っているJavaScriptモジュール化の方法です.もしあなたも初心者なら、あなたのために役に立つと思います.間違ったところがあれば、ご指摘をお願いします.
一葉斎主出典:www.cnblogs.com/yiyezhai