ホームページ >ウェブフロントエンド >jsチュートリアル >最新の JavaScript 開発プログラミング スタイル Idiomatic.js ガイド中国語版_JavaScript スキル
プロジェクトに選択するスタイルは、最高水準のものである必要があります。これをプロジェクト内の説明として配置し、コード スタイルの一貫性、読みやすさ、保守性を保証するためにこのドキュメントにリンクします。
1. 空白
1. スペースとタブを混在させないでください。
2. プロジェクトを開始し、コードを記述する前に、ソフト インデント (スペース) またはタブ (インデント方法として) を選択し、それを最高のガイドラインとして使用します。
a) 読みやすくするために、エディターでは 2 文字のインデントを設計することを常にお勧めします。これは、1 つのタブではなく 2 つのスペースまたは 2 つのスペースに相当します。
3. エディターがサポートしている場合は、「非表示の文字を表示する」設定を常にオンにしてください。利点は次のとおりです:
a) 一貫性を確保します
b) 行末のスペースを削除します
d) 送信と比較が読みやすくなります
>
2. 文法を美しくする
A. 括弧、中括弧、改行// 壊れた構文の例
while(条件) の反復 ;
for(var i=0;i // 2.A.1.1
// 読みやすさを向上させるためにスペースを使用します
// ステートメント
}
// ステートメント
}
var i,
長さ = 100;
var i = 0,
length = 100;
// ステートメント
}
for ( prop in object ) {
// ステートメント
}
// ステートメント
} else {
// ステートメント
}
var array = [],
object = {};
// スコープ (関数) 内で `var` を 1 つだけ使用すると、可読性が向上します
// 宣言リストが整理されます (キーストロークの数も節約できます)
var foo = "";
var bar = "";
var qux;
var foo = "",
bar = "",
quux;
var // これらの変数に関するコメント
foo = "",
bar = "",
quux;
// `var` ステートメントは常にそれぞれのスコープ (関数) の先頭になければなりません
// ECMAScript 6 の定数でも動作します
関数 foo() {
var bar = "",
qux;
}
function foo() {
var bar = "",
qux;
}
// 2.B.2.1
// 名前付き関数宣言
function foo( arg1, argN ) {
// 使用法
foo( arg1, argN );
// 名前付き関数宣言
function square(number) {
return number * number;
}
square( 10 ); の使用方法
// 非常に不自然な継続渡しスタイル
callback(number *number );
}
square( 10, function( square ) {
});
// 2.B.2.3
var square = function(number) {
// 価値のある関連コンテンツを返します
returnnumber *number; ;
// 識別子を持つ関数式
// この推奨形式には、それ自体を呼び出すことができる追加機能があります
var fastial = function fastial (number) {
if (数値 < 2 ) {
return 1;
}
数値 *階乗 (数値-1 );
};
// 2.B.2.4
// コンストラクター宣言
this.options = オプション;
}
// 使用法
var fooBar = new FooBar({ a: "alpha" });
fooBar.options;
// { a: "alpha" }
C. 例外、詳細
// 関数はパラメータとして `array` を受け入れますが、スペースは含まれません
foo([ "alpha", "beta" ]);
// 2.C.1.2
// この関数はパラメータとして `object` を受け入れますが、スペースは含まれません
foo({
a: "alpha",
b: "beta"
});
// 関数はパラメータとして `string` リテラルを受け入れます。スペースは使用できません
foo("bar");
//グループ化に使用される括弧内にスペースはありません
if ( !("foo" in obj) ) {
}
セクション 2.A ~ 2.C では、シンプルで高次の目的である統一に基づいた推奨アプローチとしてホワイトスペースが提案されています。 「内部空白」などの書式設定はオプションである必要がありますが、プロジェクトのソース コード全体には 1 つのタイプのみが存在する必要があることに注意してください。
if (条件) {
// ステートメント
}
while (条件) {
// ステートメント
}
for (var i = 0; i <100; i ) {
// ステートメント
}
if (true) {
// ステートメント
} else {
// ステートメント
}
一重引用符と二重引用符のどちらを選択しても、JavaScript での解析には影響しません。絶対に徹底する必要があるのは一貫性です。 同じプロジェクト内で 2 種類の引用符を決して混在させず、どちらかを選択し、一貫性を保つようにしてください。
F. 行末と空白行
空白を残すと区別が失われ、変更の使用が判読できなくなります。行末および空行内のスペースを自動的に削除する事前コミットフックを含めることを検討してください。
3. 型検出 (jQuery コア スタイル ガイドラインより)
A. 直接型 (実際の型、実際の型)
文字列:
グローバル変数:
これの意味を考えてみましょう...
指定された HTML:
// 3.B.1.1
// `foo` には値 `0` が割り当てられ、型は `number` です
var foo = 0;
// typeof foo;
// "数値"
...
// 後続のコードでは、入力要素で取得した新しい値を与えるように `foo` を更新する必要があります
foo = document.getElementById("foo-input").value;
// ここで `typeof foo` をテストすると、結果は `string` になります
// これは、`foo` を検出するための if ステートメントには次のようなロジックがあることを意味します。
if ( foo === 1 ) {
importantTask();
}
// `foo` の値が "1" であっても ` importantTask()` は実行されません
// 3.B.1.2
// / - 単項演算子を賢く使用して型をキャストすると、問題を解決できます。
foo = document.getElementById("foo-input").value;
// ^ 単項演算子は、右側のオペランドを `number`
// typeof foo;
// "数値"
if ( foo === 1 ) {
importantTask();
}
// ` importantTask()` が呼び出されます
変数番号 = 1,
文字列 = "1",
ブール = false;
数字;
// 1
数値 "";
// "1"
文字列;
// "1"
文字列;
// 1
文字列 ;
// 1
文字列;
// 2
bool;
// false
bool;
// 0
bool "";
// "false"
// 3.B.2.2
変数番号 = 1,
文字列 = "1",
ブール = true;
文字列 === 数値;
// false
文字列 === 数値 "";
// true
文字列 === 数値;
// true
bool === 数値;
// false
bool === 数値;
// true
bool === string;
// false
bool === !!string;
// true
// 3.B.2.3
var array = [ "a", "b", "c" ];
!!~array.indexOf("a");
// true
!!~array.indexOf("b");
// true
!!~array.indexOf("c");
// true
!!~array.indexOf("d");
// false
// 上記は「不必要に賢い」ものであることに注意してください
// 戻り値を比較するには明確なソリューションを使用してください
// IndexOf:
if ( array.indexOf( "a" ) >= 0 ) {
// ...
}
// 3.B.2.3
var num = 2.5;
parseInt( num, 10 );
// と同等...
~~num;
番号 > 0;
番号 >>> 0;
//結果は常に 2
// 負の値は別の方法で扱われることに常に留意してください...
var neg = -2.5;
parseInt( neg, 10 );
// と同等...
~~neg;
マイナス >> 0;
// 結果は常に -2
// しかし...
マイナス >>> 0;
//結果は 4294967294 です
4. 比較演算
// ...信頼性を判断するには、これを使用してください:
if (array.length) ...
// 4.1.2
// 配列が空かどうかを判断するだけの場合は、代わりにこれを使用します:
if (array.length === 0) ...
// ...信頼性を判断するには、これを使用してください:
if ( !array.length ) ...
// 4.1.3
// 文字列が空かどうかを判断するだけの場合は、代わりにこれを使用します:
if ( string !== "" ) ...
// ...信頼性を判断するには、これを使用してください:
if ( string ) ...
// 4.1.4
// 文字列が空かどうかを判断するだけの場合は、代わりにこれを使用します:
if ( string === "" ) ...
// ...信頼性を判断するには、これを使用してください:
if ( !string ) ...
// 4.1.5
// 参照が true かどうかを判断するだけの場合は、代わりにこれを使用します:
if ( foo === true ) ...
// ... 思ったとおりに判断し、組み込み関数の利点を享受してください:
if ( foo ) ...
// 4.1.6
// 参照が false かどうかを判断するだけの場合は、代わりにこれを使用します:
if ( foo === false ) ...
// ...感嘆符を使用して true に変換します
if ( !foo ) ...
// ...注意すべき点: これは 0、""、null、未定義、NaN に一致します
// ブール型の false でなければならない場合は、次のように使用してください:
if ( foo === false ) ...
// 4.1.7
// 参照を計算したい場合は、null または未定義でも構いませんが、false、"" または 0 ではありません。
// これを使用する代わりに、次のようにします。
if ( foo === null || foo === 未定義 ) ...
// ...次のように == 型キャストの利点をお楽しみください:
if ( foo == null ) ...
// == を使用すると、`null` は `null` および `unknown`
// に一致しますが、`false`、""、または 0 には一致しないことを覚えておいてください
null == unknown
常に最良かつ最も正確な値を判断してください。上記は独断ではなくガイドラインです。
// 最初に `===`、2 番目に `==` (緩やかに型付けされた比較が必要な場合を除く)
// `===` は型変換を行いません。これは次のことを意味します:
"1" === 1;
// false
// `==` は型を変換します。これは次のことを意味します:
"1" == 1;
// true
// 4.2.2
// ブール値、True および False
// ブール値:
true、false
// True:
"foo", 1
// 疑似:
""、0、null、未定義、NaN、void 0
5. 実践的なスタイル
(function( global ) {
var Module = (function() {
var data = "秘密";
return {
// これはブール値です
bool: true,
bool: true,
// 文字列
文字列: "文字列",
/ / array
array: [ 1, 2, 3, 4 ],
// object
object: {
lang: "en-Us"
},
getData : function() {
データ = 値 );
}
};
})();
// 他のいくつかがここに表示されます
// モジュールをグローバル オブジェクトに変換します
})( this );
// 5.2.1
(関数(グローバル) {
関数 Ctor( foo ) {
this.foo = foo;
これを返します;
}Ctor.prototype.getFoo = function() {
return this.foo;
};
Ctor.prototype.setFoo = function( val ) {
return ( this.foo = val );
};
// `new` を使用してコンストラクターを呼び出す代わりに、次のようにすることもできます:
var ctor = function( foo ) {
return new Ctor( foo );
// コンストラクターをグローバル オブジェクトに変換します
global.ctor = ctor;
6. ネーミング
A. あなたは人間のコンパイラ/コンプレッサーではないので、人間のコンパイラー/コンプレッサーになるように努めてください。
次のコードは、非常に不適切な名前付けの例です:
function q(s) {
return document.querySelectorAll(s);
}
var i,a=[],els=q("#foo");
for( i=0;i
同じロジックのコードを次に示しますが、より堅牢で適切な名前 (および読みやすい構造) が付けられています。
function query( selector ) {
return document.querySelectorAll( selector );
}
var idx = 0,
要素 = [],
一致 = query("#foo"),
長さ =matches.length;
for ( ; idx < length; idx ) {
elements.push(matches[ idx ] );
}
「犬」は文字列です
// 6.A.3.2
// 名前付き配列
`['dogs']` は、`dog 文字列を含む配列
です// 6.A.3.3
// 名前付き関数、オブジェクト、インスタンスなど
camlCase; 関数と var 宣言
// 6.A.3.4
// 名前付きビルダー、プロトタイプなど
PascalCase コンストラクター関数
// 6.A.3.5
// 名前付き正規表現
rDesc = //;
// 6.A.3.6
// Google クロージャ ライブラリ スタイル ガイドより
functionNamesLikeThis;
variableNamesLikeThis;
ConstructorNamesLikeThis;
EnumNamesLikeThis;
methodNamesLikeThis;
SYMBOLIC_CONSTANTS_LIKE_THIS;
// 継続的に呼び出される新しい非同期ストリームを作成します
stream.read( opts.path, function( data ) {
this.value = data;
// イベントトリガーの頻度を制御します
setInterval(function() {
this.emit("event");
}
function Device( opts ) {
stream.read( opts.path, _.bind(function( data ) {
this.value = データ;
}、これ) );
setInterval(_.bind(function() {
this.emit("イベント");
}, this), opts.freq 100 );
}
function Device( opts ) {
stream.read( opts.path, jQuery.proxy(function( data ) {
this.value = データ;
}、これ) );
setInterval( jQuery.proxy(function() {
this.emit("イベント");
}, this), opts.freq 100 );
}
function Device( opts ) {
stream.read( opts.path, dojo.hitch( this, function( data ) {
this.value = データ;
}) );
setInterval( dojo.hitch( this, function() {
this.emit("イベント");
})、opts.freq 100 );
}
識別子として self を使用して this のエイリアスを作成する候補を提供します。これは非常にバグが多いため、可能であれば避けてください。
function Device( opts ) {
var self = this;
this.value = null;
stream.read( opts.path, function( data ) {
self.value = データ;
});
setInterval(function() {
self.emit("イベント");
}, opts.freq || 100 );
}
C. thisArg を使用します
ES 5.1 のいくつかのプロトタイプ メソッドには特別な thisArg タグが組み込まれています。可能な限りそれを使用してください。
var obj;
obj = { f: "foo"、b: "bar"、q: "qux" };
Object.keys( obj ).forEach(function( key ) {
// |this| は `obj`
console.log( this[ key ] );
}, obj ); // <-- 最後のパラメータは `thisArg`
//印刷してください...
// "foo"
// "bar"
// "qux"
7. その他
このセクションで説明するアイデアや概念は独断的なものではありません。代わりに、一般的な JavaScript プログラミング タスクにより良いソリューションを提供しようとする既存の慣行に対する好奇心を刺激します。
A. switch の使用は避けてください。最新のメソッド トレースでは switch 式を含む関数がブラックリストに登録されます。
Firefox と Chrome の最新バージョンでは switch ステートメントが大幅に改善されたようです。 http://jsperf.com/switch-vs-object-literal-vs-module
改善点がここで確認できることは注目に値します: https://github.com/rwldrn/idiomatic.js/issues/13
switch( foo ) {
case "alpha":
alpha();
Break;
case "beta":
beta();
Break;
default:
//デフォルトブランチ
Break;
}
// 7.A.1.2
// 構成と再利用をサポートする 1 つの方法は、オブジェクトを使用して「ケース」を保存することです。
// 関数を使用して委任します。
var ケース、委任者;
// 戻り値は説明のみです
cases = {
alpha: function() {
// ステートメント
// 戻り値
return [ "Alpha", argument .length ];
},
beta: function() {
// Statement
// 戻り値
return [ "Beta", argument.length ];
} ,
_default: function() {
// Statement
// 戻り値
return [ "Default", argument.length ];
}
};
delegator = function() {
var args, key, delegate;
// `argument` を配列に変換します
args = [].slice.call( argument );
// `argument` から最初の値を抽出します
key = args.shift();
// デフォルトのブランチを呼び出します
delegate = case._default;
// オブジェクトからメソッドをデリゲートします
if (cases.hasOwnProperty( key ) ) {
delegate = case[ key ];
}
// arg のスコープは特定の値に設定できます。
// この場合、|null| で問題ありません
return delegate.apply( null, args );
};
// 7.A.1.3
// 7.A.1.2 の API の使用:
delegator( "alpha", 1, 2, 3, 4, 5 );
// [ "Alpha", 5 ]
// もちろん、`case` キーの値は任意の値に簡単に変更できます
var caseKey, someUserInput;
// 何らかの形式の入力である可能性はありますか?
someUserInput = 9;
if ( someUserInput > 10 ) {
caseKey = "alpha";
} else {
caseKey = "beta";
}
// または...
caseKey = someUserInput > 10 ? "アルファ" : "ベータ";
// それでは...
delegator( caseKey, someUserInput );
// [ "Beta", 1 ]
// もちろん、この方法でもできます...
delegator();
// [ "デフォルト", 0 ]
B. 値を早めに返すと、パフォーマンスに大きな違いがなくコードの可読性が向上します
if ( foo ) {
ret = "foo";
} else {
ret = "quux";
}
return ret;
}
// OK:
関数 returnEarly( foo ) {
if ( foo ) {
return "foo";
}
return "quux";
}
8. ネイティブ オブジェクトとホスト オブジェクト (注: 実は、ホスト オブジェクトは翻訳すべきではないと常々感じていたので、一般の書籍に書かれている方法に従って翻訳します)
最も基本的な原則は次のとおりです:
愚かなことはしないでください。事態は必ず良くなります。
この考えを強化するには、次のデモをご覧ください:
「すべてが許可されています: ネイティブ拡張機能」Andrew Dupont 著 (JSConf2011、オレゴン州ポートランド)
http://blip.tv/jsconf/jsconf2011-andrew-dupont-everything-is-permitted-extending-built-ins-5211542
9. 注意事項
コードの上に配置される単一行コメントが推奨されます
複数行も可能です
行末コメントは避けるべきです!
JSDoc メソッドも有効ですが、時間がかかります
10. 1 つの言語を使用します
プログラムは、プログラム管理者 (またはチーム) が指定した言語に関係なく、同じ言語でのみ作成する必要があります。
付録
カンマファースト
このドキュメントを基本的なスタイル ガイドとして使用するすべてのプロジェクトでは、明示的に指定または作成者によって要求されない限り、先頭にカンマを使用したコードの書式設定が許可されません。