javascriptのオブジェクト作成モード
13829 ワード
javascriptでは、オブジェクトの字面量や構造関数を使ってオブジェクトを作成することができると知っていますが、どのように優雅にオブジェクトを作成するかは分かりません.
前人は無数の穴を踏んで、また無数の穴を埋めた後、異なる場面のいくつかのオブジェクトの作成パターンをまとめました.名前空間モデル モジュールモード サンドボックスモード チェーンモード 名前付きモード
プラグインを書いていると、このプラグインの内部に多くのグローバル変数が使用されますが、この場合、どのように変数が他のプラグインの変数と命名に衝突しないことを保証しますか?私たちは、javascriptに名前空間が内蔵されていないことを知っています.後の変数は前の変数を上書きします.どうやってこの問題を避けるべきですか?
もう考えているかもしれませんが、十分なユニークなネーミングさえあればいいですよね.例えば、リリンショーVarは確かにできますが、変数が多いなら、それぞれに独特なネーミングをしますか?疲れていますか?そしてメンテナンスも大変です.
ネーミングモードは、アプリケーションのためにグローバルオブジェクトを作成し、MYAPPなどのすべての変数と関数をこのグローバルオブジェクト(MYAPP)の属性に掛けると提案しています.
利点:コード中の命名衝突を避ける. コードと第三者の命名衝突を避ける 欠点より多くの文字を入力する必要があります. の任意の部分のコードは、グローバル・インスタンス を修正することができる.ネストされた額数は、より長い属性クエリ解析を意味する. では、これらの欠陥を避ける方法はありますか?コード依存関係を宣言するのはいいアイデアです.
依存関係を宣言する可読性が高い ローカル変数を解析する速度は、常にグローバル変数を解析する速度よりも速いです. 減少コード量 名前空間
プログラムの複雑さが増すにつれて、全体のオブジェクトに新しい属性が元の属性をカバーしないようにするにはどうすればいいですか?これは新しい属性を追加する前に、既に存在しているかどうかを確認する必要があります.
モジュールモード
実はモジュールモードは多種のモードの組み合わせです.名前空間 即時関数 プライベートおよび特権関数 ステートメント依存性
モジュールをラッピングしたリアルタイム関数にパラメータを渡すことができ、リアルタイム関数におけるグローバルシンボルの解析を加速させることができます.
同じページで同じライブラリの2つのバージョンを実行する必要があると仮定しますが、残念ながら、前の2つの作成モードはサポートされていません.この場合はモジュール化が必要です.
ネーミングモードには大域的なオブジェクトがあります.シャドーモードには大域的な構造関数があります.ここではSandboxと名づけます.このコンストラクタは、オブジェクトのインスタンスに必要なモジュール名と、フィードバック関数を指定する1つ以上のパラメータを受信することができる.例えば:はモジュール化を実現し、同じページが同じライブラリの異なるバージョンを使用できない問題を解決する. ポイントで区切られた名前の解析時間を最適化しました.例えば、MYAPP.untilities.array チェーンモード
チェーンモードでは、前の操作で返した値を変数に支払うことなく、次から次へとオブジェクトを呼び出すことができます.複数の行に分割する必要はありません.例えば:
長所入力を節約する文字 は、関数を分割し、コードの維持性を向上させるために役立ちます.
欠点 調整が困難で、問題が発生したら、具体的なステップ に位置決めすることが困難である.
各デザインパターンにはそれぞれ長所と短所があります.具体的にどのモデルを使うかはプロジェクトのニーズを見なければなりません.みんなで勉強しましょう.
前人は無数の穴を踏んで、また無数の穴を埋めた後、異なる場面のいくつかのオブジェクトの作成パターンをまとめました.
プラグインを書いていると、このプラグインの内部に多くのグローバル変数が使用されますが、この場合、どのように変数が他のプラグインの変数と命名に衝突しないことを保証しますか?私たちは、javascriptに名前空間が内蔵されていないことを知っています.後の変数は前の変数を上書きします.どうやってこの問題を避けるべきですか?
もう考えているかもしれませんが、十分なユニークなネーミングさえあればいいですよね.例えば、リリンショーVarは確かにできますが、変数が多いなら、それぞれに独特なネーミングをしますか?疲れていますか?そしてメンテナンスも大変です.
ネーミングモードは、アプリケーションのためにグローバルオブジェクトを作成し、MYAPPなどのすべての変数と関数をこのグローバルオブジェクト(MYAPP)の属性に掛けると提案しています.
//
var MYAPP = {};
//
MYAPP.parent = function () {};
MYAPP.child = function () {};
//
MYAPP.some_var = 1;
//
MYAPP.modules = {}
//
MYAPP.modules.module1 = {};
MYAPP.modules.module2 = {};
ネーミングの約束:通常はすべての大文字でこのグローバルオブジェクトに名前を付けます.利点:
依存関係を宣言する
var myFunction = function () {
//
var event = MYAPP.util.event,
dom = MYAPP.util.dom;
//...
}
利点:プログラムの複雑さが増すにつれて、全体のオブジェクトに新しい属性が元の属性をカバーしないようにするにはどうすればいいですか?これは新しい属性を追加する前に、既に存在しているかどうかを確認する必要があります.
var MYAPP = MYAPP || {};
MYAPP.name = function (ns_string) {
var parts = ns_string.split('.'),
parent = MYAPP,
i;
//
if (parts[0] === 'MYAPP') {
parts = parts.slice(1);
}
for(i = 0; i < parts.length; i++) {
//
if (typeof parent[parts[i]] === 'undefined') {
parent[parts[i]] = {};
}
parent = parent[parts[i]];
}
return parent;
}
ネーミングモードは使いやすいですが、問題があります.つまり、どの部分のコードでもグローバルインスタンスを修正できます.また、中の属性はどうやって回避できますか?私たちは、S 5にはクラスの概念がないことを知っています.プライベートメンバを実現するためには、この特性をシミュレーションするためにクローズドを使用することができます.モジュールモード
実はモジュールモードは多種のモードの組み合わせです.
MYAPP.ntilities.array = (function () {
//
var uobj = MYAPP.ntilities.object,
ulang = MYAPP.ntilities.lang;
//
var array_string = '[object array]',
ops = Object.prototype.toString;
//
//...
//
// API
return {
inArray: function (needle, haystack) { ... },
isArray: function (str) { ... }
// ...
}
})()
グローバル変数をモジュールにインポートします.モジュールをラッピングしたリアルタイム関数にパラメータを渡すことができ、リアルタイム関数におけるグローバルシンボルの解析を加速させることができます.
MYAPP.ntilities.array = (function (app, global) {
}(MYAPP, this);
サンドボックスモード同じページで同じライブラリの2つのバージョンを実行する必要があると仮定しますが、残念ながら、前の2つの作成モードはサポートされていません.この場合はモジュール化が必要です.
ネーミングモードには大域的なオブジェクトがあります.シャドーモードには大域的な構造関数があります.ここではSandboxと名づけます.このコンストラクタは、オブジェクトのインスタンスに必要なモジュール名と、フィードバック関数を指定する1つ以上のパラメータを受信することができる.例えば:
//
Sandbox(['ajax', 'dom'], function () { // });
// , ,
Sandbox('ajax', 'dom', function () { // });
// '*',
Sandbox(function () { // });
Sandbox('*', function () { // });
実際のコンストラクタを実現する前に、まずSandboxのためにmodulesという静的な属性を追加します.これはSandboxがオブジェクトであることを理解する必要があります.Sandbox.modules = {}
必要なモジュールをSandbox.modulesオブジェクトに追加します.私たちは全部でdom、ajax、イベントモジュールが必要だと仮定します.Sandbox.modules.dom = function(box) {
box.getElement = function () {};
};
Sandbox.modules.ajax = function(box) {
box.getResponse = function () {};
};
Sandbox.modules.event = function(box) {
box.attachEvent = function () {};
};
次にコンストラクタを実現します.function Sandbox = function () {
//
var args = Array.prototype.slice.call(arguments),
//
callback = args.pop(),
//args[0] String , ,
modules = (args[0] && typeof args[0] === 'String') ? args : arg[0],
i;
//
if(!(this instanceof Sandbox)) {
return new Sandbox (modules, callback);
}
// this , ,
this.a = 1;
this.b = 2;
// 'this'
// '*',
if (!modules || modules === '*') {
modules = [];
for (i in Sandbox.modules) {
modules.push[i];
}
}
//
for(i = 0; i < modules.lenght; i++) {
Sandbox.modules[modules[i]](this)
}
// ,
callback();
}
// ,
Sanndbox.prototype = {
name: 'MY Application',
version: '1.0',
getName: function () {
return this.name;
}
};
長所チェーンモードでは、前の操作で返した値を変数に支払うことなく、次から次へとオブジェクトを呼び出すことができます.複数の行に分割する必要はありません.例えば:
myobj.method1('hello').method2().method3('str');
これはよく分かります.直接コードを見に来ます.var obj = {
al: 1,
add: function (v) {
this.val += v;
return this;
},
set: function (v) {
this.val = v;
return this;
},
shout: function (v) {
console.log(this.val);
}
};
//
obj.add(1).set(2).shout();
objの各方法はthisオブジェクトに戻ります.これはチェーン式を実現する原理です.長所
欠点
各デザインパターンにはそれぞれ長所と短所があります.具体的にどのモデルを使うかはプロジェクトのニーズを見なければなりません.みんなで勉強しましょう.