ホームページ >ウェブフロントエンド >jsチュートリアル >最新の JavaScript 開発プログラミング スタイル Idiomatic.js ガイド中国語版_JavaScript スキル

最新の JavaScript 開発プログラミング スタイル Idiomatic.js ガイド中国語版_JavaScript スキル

WBOY
WBOYオリジナル
2016-05-16 16:46:341459ブラウズ

プロジェクトに選択するスタイルは、最高水準のものである必要があります。これをプロジェクト内の説明として配置し、コード スタイルの一貫性、読みやすさ、保守性を保証するためにこのドキュメントにリンクします。

1. 空白

1. スペースとタブを混在させないでください。
2. プロジェクトを開始し、コードを記述する前に、ソフト インデント (スペース) またはタブ (インデント方法として) を選択し、それを最高のガイドラインとして使用します。
a) 読みやすくするために、エディターでは 2 文字のインデントを設計することを常にお勧めします。これは、1 つのタブではなく 2 つのスペースまたは 2 つのスペースに相当します。
3. エディターがサポートしている場合は、「非表示の文字を表示する」設定を常にオンにしてください。利点は次のとおりです:
a) 一貫性を確保します
b) 行末のスペースを削除します
d) 送信と比較が読みやすくなります
>

2. 文法を美しくする

A. 括弧、中括弧、改行


コードをコピーします コードは次のとおりです:
// if/else/for/while/try には通常、括弧、中括弧、複数の行が含まれます
// これは読みやすさに役立ちます
// 2.A.1.1

// 壊れた構文の例

if(条件) doSomething();

while(条件) の反復 ;

for(var i=0;i // 2.A.1.1

// 読みやすさを向上させるためにスペースを使用します

if (条件) {

// ステートメント
}

while (条件) {

// ステートメント
}

for ( var i = 0; i // ステートメント
}
// より良いアプローチ:

var i,

長さ = 100;

for ( i = 0; i // ステートメント
}
// または...

var i = 0,

length = 100;

for ( ; i < length; i ) {

// ステートメント
}

var prop;

for ( prop in object ) {

// ステートメント
}

if ( true ) {

// ステートメント
} else {
// ステートメント
}

B. 代入、宣言、関数 (名前付き関数、関数式、コンストラクター関数)

コードをコピー コードは次のとおりです。
// 2.B. 1.1
// 変数
var foo = "bar",
num = 1,
undef;

//リテラル​​識別子:

var array = [],
object = {};

// 2.B.1.2

// スコープ (関数) 内で `var` を 1 つだけ使用すると、可読性が向上します
// 宣言リストが整理されます (キーストロークの数も節約できます)

// 悪い

var foo = "";
var bar = "";
var qux;

// OK

var foo = "",
bar = "",
quux;

// または..

var // これらの変数に関するコメント
foo = "",
bar = "",
quux;

// 2.B.1.3

// `var` ステートメントは常にそれぞれのスコープ (関数) の先頭になければなりません
// ECMAScript 6 の定数でも動作します

// 不正な

関数 foo() {

// 変数の前にステートメントがあります

var bar = "",

qux;
}

// OK

function foo() {
var bar = "",
qux;

// すべてのステートメントは変数の後にあります

}
// 2.B.2.1
// 名前付き関数宣言
function foo( arg1, argN ) {

}

// 使用法

foo( arg1, argN );

// 2.B.2.2

// 名前付き関数宣言
function square(number) {
return number * number;
}

//

square( 10 ); の使用方法
// 非常に不自然な継続渡しスタイル

function square(number, callback) {

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
// コンストラクター宣言

function FooBar( options) {


this.options = オプション;
}

// 使用法
var fooBar = new FooBar({ a: "alpha" });

fooBar.options;
// { a: "alpha" }


C. 例外、詳細


コードをコピー コードは次のとおりです:

// 2.C.1.1
// コールバック付き関数
foo(function() {
// 注: 最初の関数呼び出しの括弧と `function` は次のとおりです。スペースは使用できません
});

// 関数はパラメータとして `array` を受け入れますが、スペースは含まれません
foo([ "alpha", "beta" ]);

// 2.C.1.2
// この関数はパラメータとして `object` を受け入れますが、スペースは含まれません
foo({
a: "alpha",
b: "beta"
});

// 関数はパラメータとして `string` リテラルを受け入れます。スペースは使用できません
foo("bar");

//グループ化に使用される括弧内にスペースはありません
if ( !("foo" in obj) ) {

}


D. 一貫性は常に勝利します

セクション 2.A ~ 2.C では、シンプルで高次の目的である統一に基づいた推奨アプローチとしてホワイトスペースが提案されています。 「内部空白」などの書式設定はオプションである必要がありますが、プロジェクトのソース コード全体には 1 つのタイプのみが存在する必要があることに注意してください。

コードをコピー コードは次のとおりです:

// 2.D.1.1

if (条件) {
// ステートメント
}

while (条件) {
// ステートメント
}

for (var i = 0; i <100; i ) {
// ステートメント
}

if (true) {
// ステートメント
} else {
// ステートメント
}


引用符

一重引用符と二重引用符のどちらを選択しても、JavaScript での解析には影響しません。絶対に徹底する必要があるのは一貫性です。 同じプロジェクト内で 2 種類の引用符を決して混在させず、どちらかを選択し、一貫性を保つようにしてください。

F. 行末と空白行

空白を残すと区別が失われ、変更の使用が判読できなくなります。行末および空行内のスペースを自動的に削除する事前コミットフックを含めることを検討してください。

3. 型検出 (jQuery コア スタイル ガイドラインより)

A. 直接型 (実際の型、実際の型)

文字列:

コードをコピー コードは次のとおりです:

変数の型 == = "文字列 "

番号:
コードをコピー コードは次のとおりです:

変数の型 = == "数値"

ブール値:
コードをコピー コードは次のとおりです:

変数の型 === "boolean"

オブジェクト:
コードをコピー コードは次のとおりです:

変数の型 === "object"

配列:
コードをコピー コードは次のとおりです。

Array.isArray( arrayLikeObject )
(可能な場合)

Node:
コードをコピー コードは次のとおりです:

elem.nodeType === 1

null :
コードをコピー コードは次のとおりです:

variable === null

null または未定義:
コードをコピー コードは次のとおりです:

variable = = null

未定義:

グローバル変数:

コードをコピー コードは次のとおりです:

変数の型 = == " 未定義"

ローカル変数:
コードをコピー コードは次のとおりです:

変数 === 未定義

属性:
コードをコピー コードは次のとおりです。

object.prop === 未定義
object.hasOwnProperty( prop )
オブジェクト内の「prop」

B. 変換タイプ (強制タイプ、強制タイプ)

これの意味を考えてみましょう...

指定された 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()` が呼び出されます


キャストの例をいくつか示します:
コードをコピー コードは次のとおりです:

// 3.B.2.1

変数番号 = 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. 比較演算

コードをコピー コードは次のとおりです:

// 4.1.1
// 配列に長さがあるかどうかを判断するだけの場合は、代わりにこれを使用します:
if ( array.length > 0 ) ...

// ...信頼性を判断するには、これを使用してください:
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

常に最良かつ最も正確な値を判断してください。上記は独断ではなくガイドラインです。

コードをコピーします コードは次のとおりです:

// 4.2.1
/ / 型変換と比較演算命令

// 最初に `===`、2 番目に `==` (緩やかに型付けされた比較が必要な場合を除く)

// `===` は型変換を行いません。これは次のことを意味します:

"1" === 1;
// false

// `==` は型を変換します。これは次のことを意味します:

"1" == 1;
// true

// 4.2.2
// ブール値、True および False

// ブール値:
true、false

// True:
"foo", 1

// 疑似:
""、0、null、未定義、NaN、void 0

5. 実践的なスタイル

コードをコピーします コードは次のとおりです:

// 5.1.1
// 実用的なモジュール

(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() {
データ = 値 );
}
};
})();

// 他のいくつかがここに表示されます

// モジュールをグローバル オブジェクトに変換します

global.Module = Module;

})( 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;

})( this );

6. ネーミング

A. あなたは人間のコンパイラ/コンプレッサーではないので、人間のコンパイラー/コンプレッサーになるように努めてください。

次のコードは、非常に不適切な名前付けの例です:

コードをコピーします コードは次のとおりです:

// 6.A.1.1
// サンプル コードの名前が適切ではありません

function q(s) {
return document.querySelectorAll(s);
}
var i,a=[],els=q("#foo");
for( i=0;i


間違いなく、あなたはそのようなコードを書いています - 今日から二度と現れないことを願っています。

同じロジックのコードを次に示しますが、より堅牢で適切な名前 (および読みやすい構造) が付けられています。

コードをコピー コードは次のとおりです:

// 6.A.2.1
// 改良された名前付けサンプル コード

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.1
// 名前付き文字列

「犬」は文字列です

// 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;


B. これに直面してください。 よく知られている呼び出しと適用の使用に加えて、常に .bind( this ) またはそれと同等の機能を使用することをお勧めします。より良い代替手段がない場合にのみエイリアスを使用して、後続の呼び出し用に BoundFunction 宣言を作成します。


コードをコピーします コードは次のとおりです:
// 6.B.1
関数デバイス (オプション) {
this.value = null;

// 継続的に呼び出される新しい非同期ストリームを作成します

stream.read( opts.path, function( data ) {

// ストリームを使用してデータの最新の値を返し、インスタンスの値を更新します

this.value = data;

}.bind(this) );

// イベントトリガーの頻度を制御します

setInterval(function() {

// 制御されたイベントを発行します

this.emit("event");

}.bind(this), opts.freq || 100 );

}

// イベントエミッター (EventEmitter) を継承したと仮定します ;)

それが機能しない場合は、.bind と同等の機能が最新の JavaScript ライブラリで利用できます。


コードをコピーします コードは次のとおりです:
// 6.B.2
// 例: lodash/underscore, _.bind()

function Device( opts ) {

this.value = null;

stream.read( opts.path, _.bind(function( data ) {

this.value = データ;

}、これ) );

setInterval(_.bind(function() {

this.emit("イベント");

}, this), opts.freq 100 );

}

// 例: jQuery.proxy

function Device( opts ) {

this.value = null;

stream.read( opts.path, jQuery.proxy(function( data ) {

this.value = データ;

}、これ) );

setInterval( jQuery.proxy(function() {

this.emit("イベント");

}, this), opts.freq 100 );

}

// 例: dojo.hitch

function Device( opts ) {

this.value = null;

stream.read( opts.path, dojo.hitch( this, function( data ) {

this.value = データ;

}) );

setInterval( dojo.hitch( this, function() {

this.emit("イベント");

})、opts.freq 100 );

}


識別子として self を使用して this のエイリアスを作成する候補を提供します。これは非常にバグが多いため、可能であれば避けてください。

コードをコピー コードは次のとおりです:

// 6.B.3

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 タグが組み込まれています。可能な限りそれを使用してください。

コードをコピー コードは次のとおりです:

// 6.C.1

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"


thisArg は Array.prototype.every、Array.prototype.forEach、Array にあります。プロトタイプ .some、Array.prototype.map、Array.prototype.filter で使用できます。

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

コードをコピー コードは次のとおりです:

// 7.A.1.1
// Switch ステートメントの例

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. 値を早めに返すと、パフォーマンスに大きな違いがなくコードの可読性が向上します

コードをコピーします コードは次のとおりです:

// 7.B.1.1
// 悪い:
function returnLate( foo ) {
var ret;

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 つの言語を使用します

プログラムは、プログラム管理者 (またはチーム) が指定した言語に関係なく、同じ言語でのみ作成する必要があります。

付録

カンマファースト

このドキュメントを基本的なスタイル ガイドとして使用するすべてのプロジェクトでは、明示的に指定または作成者によって要求されない限り、先頭にカンマを使用したコードの書式設定が許可されません。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。