Xiao Aは、特定の起業家チームのフロントエンドエンジニアであり、プロジェクトJavaScriptプログラムの作成を担当しています。
グローバル変数の競合
彼自身の経験によると、Xiaoは最初にいくつかの一般的に使用される関数を抽出し、それらを関数に書き、パブリックファイルBase.jsに入れました:
コードコピーは次のとおりです。
var _ = {
$:function(id){return document.getElementById(ID); }、
getCookie:function(key){...}、
SetCookie:function(key、value){...}
};
Xiao Aは、これらの関数を_オブジェクトに入れて、あまりにも多くのグローバル変数が競合を引き起こすのを防ぎます。彼は他のチームに、誰かがこれらの機能を使用したい場合は、base.jsを紹介するだけであると語った。
Xiao CはXiao Aの同僚です。彼はXiaoに次のように語った。彼のページはunderscore.jsというクラスライブラリを導入し、このクラスライブラリも「base.js」と競合するこのグローバル変数を占有します。 Xiaoは、Underscore.jsはサードパーティライブラリであり、変更することはおそらく困難であると考えていますが、base.jsは多くのページに広がっており、変更することは不可能です。最終的に、Xiao Aは、Underscore.jsによって占有されているグローバル変数を変更する以外に選択肢がありませんでした。
この時点で、Xiao Aは、名前空間に関数を置くことで、グローバル変数の競合の確率を低下させる可能性があることを発見しましたが、グローバル変数競合の問題は解決しません。
頼る
ビジネスの開発により、Xiao Aは、base.jsおよびutil.jsで関数を呼び出す必要があるタグスイッチングコンポーネントタブなどの一連の関数ライブラリとUIコンポーネントを作成しました。
ある日、新しい同僚のXiao DとXiao Aは、彼がページにtabs.jsを引用したと報告しましたが、機能は正常ではありませんでした。 Xiao Aは一目で問題を発見しました。 Xiao Dは、tabs.jsがbase.jsとutil.jsに依存していることを知らなかったため、これら2つのファイルに参照を追加しなかったことが判明しました。それで彼はすぐに変更を加えました:
コードコピーは次のとおりです。
<スクリプトsrc = "tabs.js"> </script>
<スクリプトsrc = "base.js"> </script>
<スクリプトsrc = "util.js"> </script>
ただし、機能はまだ異常です。この時点で、XiaoはXiao Dに教訓を教えました。 Xiao dはbase.jsとutil.jsをタブの後に入れたことがわかりました。
Xiaoは、彼が著者であり、当然コンポーネントの依存を知っていると考えていますが、他の人、特に新人は言うのは難しいです。
しばらくすると、Xiaoはタグスイッチングコンポーネントに機能します。この関数を実装するには、tabs.jsもui.jsで関数を呼び出す必要があります。この時点で、Xiao Aは深刻な問題を発見しました。彼は、tabs.jsと呼ばれるすべてのページにui.js参照を追加する必要がありました! ! !
しばらくすると、Xiaoは最適化されたtabs.jsであり、このコンポーネントはutil.jsに依存しなくなるため、タブを使用するすべてのページからutil.jsへの参照を削除してパフォーマンスを向上させました。彼が修正を加えたとき、彼に何か大きなことが起こりました。テストチームのMMは、いくつかのページが異常であると彼に言った。 Xiaoがそれを見たとき、彼は突然、いくつかのページの他の機能がutil.jsで機能を使用していることに気付きました。彼はこのファイルへの参照を削除し、エラーを引き起こしました。関数が正常であることを確認するために、彼は再びコードを復元しました。
Xiaoもう一度考えて、ページを1つずつ変更せずに依存関係を変更する方法はありますか?他の機能には影響しませんか?
モジュラー
Xiao Aがインターネットで買い物をしていたとき、彼は以前に遭遇したすべての問題を解決できる新しいモジュラーエンコード方法を誤って発見しました。
モジュラープログラミングでは、各ファイルはモジュールです。各モジュールは、defineという関数によって作成されます。たとえば、base.jsをモジュールに変換した後、コードは次のようになります。
コードコピーは次のとおりです。
定義(関数(要求、エクスポート、モジュール){
exports。$ = function(id){return document.getElementById(id); };
Exports.getCookie = function(key){...};
Exports.setCookie = function(key、value){...};
});
base.jsが提供するすべてのインターフェイスは、エクスポートオブジェクトに追加されます。エクスポートはローカル変数であり、モジュール全体のコードはグローバル変数の半分を占有していません。
では、特定のモジュールが提供するインターフェイスをどのように呼び出しますか?例としてtabs.jsを取ると、base.jsとutil.jsに依存します。
コードコピーは次のとおりです。
定義(関数(要求、エクスポート、モジュール){
var _ = require( 'base.js')、util = require( 'util.js');
var div_tabs = _。$( 'tabs');
// ....その他のコード
});
モジュールは、ローカル関数が必要で他のモジュールのインターフェイスを取得できます。現時点では、変数_とutilは両方ともローカル変数であり、変数名は開発者によって完全に制御されています。 _が気に入らない場合は、ベースを使用することもできます。
コードコピーは次のとおりです。
定義(関数(要求、エクスポート、モジュール){
var base = require( 'base.js')、util = require( 'util.js');
var div_tabs = base。$( 'tabs');
// ....その他のコード
});
util.jsを削除してui.jsを追加すると、tabs.jsを変更するだけです。
コードコピーは次のとおりです。
定義(関数(要求、エクスポート、モジュール){
var base = require( 'base.js')、ui = require( 'ui.js');
var div_tabs = base。$( 'tabs');
// ....その他のコード
});
ローダ
ネイティブブラウザのサポートが不足しているため、モジュール式の方法でエンコードしたい場合は、ローダーと呼ばれるものに依存する必要があります。
現在、require.jsやSeajsなど、ローダーの多くの実装があります。 Jraiserクラスライブラリには、独自のローダーもあります。