プロジェクトに選択するスタイルは、最高の基準でなければなりません。プロジェクトの説明としてそれを配置し、コードスタイルの一貫性、読みやすさ、保守性の保証としてこのドキュメントにリンクします。
1。空白
1.スペースとタブを混ぜないでください。
2。プロジェクトを開始し、コードを作成する前にソフトインデント(スペース)またはタブ(インデント方法として)を選択し、最高の基準として使用します。
a)。読みやすさのために、編集で2文字の幅のインデントを設計することを常にお勧めします。これは、タブの代わりに2つのスペースまたは2つのスペースに相当します。
3.編集者がサポートしている場合は、常に「目に見えないキャラクターを表示」設定をオンにします。利点は次のとおりです。
a)。一貫性を確保します
b)。行の端にあるスペースを取り外します
c)。空白を削除します
d)。提出と比較はより読みやすくなります
2。文法を美化します
A.ブレース、ブレース、ラインブレーク
コードコピーは次のとおりです。
// if/else/for/while/tryは通常ブレース、巻き毛の装具、複数の行があります
//これは読みやすいです
// 2.a.1.1
//難しい構文の例
if(条件)dosomething();
while(条件)反復++;
for(var i = 0; i <100; i ++)sometiterfn();
// 2.a.1.1
//スペースを使用して読みやすさを向上させます
if(条件){
// 声明
}
while(条件){
// 声明
}
for(var i = 0; i <100; i ++){
// 声明
}
//より良い練習:
var i、
長さ= 100;
for(i = 0; i <length; i ++){
// 声明
}
// または...
var i = 0、
長さ= 100;
for(; i <length; i ++){
// 声明
}
var prop;
for(オブジェクトの小道具){
// 声明
}
if(true){
// 声明
} それ以外 {
// 声明
}
B.割り当て、宣言、関数(機能、関数式、コンストラクター関数)
コードコピーは次のとおりです。
// 2.B.1.1
// 変数
var foo = "bar"、
num = 1、
undef;
//リテラル識別:
var array = []、
object = {};
// 2.B.1.2
//スコープ内で1つの「var」のみを使用する(関数)
//ステートメントリストを整然としてください(いくつかのキーボードタイピングも節約できます)
// 良くない
var foo = "";
var bar = "";
var qux;
// 良い
var foo = ""、
bar = ""、
QUUX;
// または..
var //これらの変数に関するコメント
foo = ""、
bar = ""、
QUUX;
// 2.B.1.3
//「var」ステートメントは常に各スコープの最上部にある必要があります(関数)
//また、ECMAScript 6の定数に適しています
// 良くない
function foo(){
//変数の前にステートメントがあります
var bar = ""、
qux;
}
// 良い
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;
}
//使用方法
正方形(10);
//非常に不自然な継続パススタイル
function square(number、callback){
callback(number * number);
}
正方形(10、関数(正方形){
//コールバックコンテンツ
});
// 2.B.2.3
//関数式
var square = function(number){
//貴重で関連するコンテンツを返します
return number * number;
};
//識別子を使用した関数式
//この優先フォームには、それ自体を呼び出すことができる追加の機能があります
//スタックに識別子があります
var factorial = function factorial(number){
if(number <2){
返品1;
}
return number * factorial(number-1);
};
// 2.B.2.4
//コンストラクター宣言
function foobar(option){
this.options = options;
}
//使用方法
var foobar = new foobar({a: "alpha"});
foobar.options;
// {a: "alpha"}
C.例外、詳細
コードコピーは次のとおりです。
// 2.C.1.1
//コールバックを使用して機能します
foo(function(){
//注:最初の関数呼び出しの括弧内にスペースがなく、「機能」がありません
});
//関数は、スペースなしで「配列」を引数として受け入れます
foo(["alpha"、 "beta"]);
// 2.C.1.2
//関数は、スペースなしで「オブジェクト」を引数として受け入れます
foo({
A:「アルファ」、
B:「ベータ」
});
//関数は、スペースなしで「文字列」を引数として受け入れます
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){
// 声明
} それ以外 {
// 声明
}
E.引用符
単一の引用符を選択するか二重引用符を選択するかは関係ありませんが、JavaScriptに解析の違いはありません。絶対に義務付けられる必要があるのは一貫性です。同じプロジェクトで2つの引用を混ぜたり、1つを選択したり、一貫性を保ちたりしないでください。
F.行の終わりと空の線
空白のままにすると、違いが壊れ、使用の使用は読めません。ラインの端と空白線のスペースを自動的に削除する事前にコミットされたフックを含めることを検討してください。
3.タイプ検出(jQueryコアスタイルガイドラインから)
A.ダイレクトタイプ(実際のタイプ、実際のタイプ)
弦:
コードコピーは次のとおりです。
typeof変数=== "string"
番号:
コードコピーは次のとおりです。
typeof変数=== "number"
Boolean:
コードコピーは次のとおりです。
typeof変数=== "boolean"
物体:
コードコピーは次のとおりです。
typeof変数=== "Object"
配列:
コードコピーは次のとおりです。
array.isarray(arraylikeObject)
(もし可能なら)
ノード:
コードコピーは次のとおりです。
ELEM.NODETYPE === 1
ヌル:
コードコピーは次のとおりです。
変数=== null
ヌルまたは未定義:
コードコピーは次のとおりです。
変数== null
未定義:
グローバル変数:
コードコピーは次のとおりです。
typeof変数===「未定義」
ローカル変数:
コードコピーは次のとおりです。
変数===未定義
財産:
コードコピーは次のとおりです。
object.prop === undefined
object.hasownproperty(prop)
オブジェクトの「プロップ」
B.タイプ(強制タイプ、強制タイプ)を変換する
次の意味を考えてみましょう...
HTMLを与えられた:
コードコピーは次のとおりです。
<入力型= "text" id = "foo-input" value = "1">
// 3.B.1.1
// `foo`に` 0`の値が割り当てられています。
var foo = 0;
// typeof foo;
// "番号"
...
//後続のコードでは、「foo」を更新し、入力要素で取得した新しい値を割り当てる必要があります
foo = document.getElementById( "foo-input")。value;
//「typeof foo`」をテストすると、結果は「string」になります
//これは、ifステートメントで「foo」を検出するときにこれに似たロジックがあることを意味します。
if(foo === 1){
重要なtask();
}
// `falytask()`は「1」の値がある場合でも、実行されることはありません。
// 3.B.1.2
// +/- unaryオペレーターを巧みに使用してタイプをキャストして問題を解決できます。
foo = +document.getElementById( "foo-input")。value;
// ^ +統一オペレーターは、操作オブジェクトを右に「number」に変換します
// typeof foo;
// "番号"
if(foo === 1){
重要なtask();
}
// `falitytask()`が呼び出されます
キャストのいくつかの例を次に示します。
コードコピーは次のとおりです。
// 3.B.2.1
var番号= 1、
string = "1"、
bool = false;
番号;
// 1
番号 + "";
// "1"
弦;
// "1"
+文字列;
// 1
+string ++;
// 1
弦;
// 2
ブール;
// 間違い
+bool;
// 0
bool + "";
// "間違い"
// 3.B.2.2
var番号= 1、
string = "1"、
bool = true;
string === number;
// 間違い
string === number + "";
// 真実
+文字列===番号;
// 真実
bool === number;
// 間違い
+bool === number;
// 真実
bool === string;
// 間違い
bool === !!文字列;
// 真実
// 3.B.2.3
var array = ["a"、 "b"、 "c"];
!! 〜ARRAY.INDEXOF( "A");
// 真実
!! 〜ARRAY.INDEXOF( "B");
// 真実
!! 〜ARRAY.INDEXOF( "C");
// 真実
!! 〜ARRAY.INDEXOF( "d");
// 間違い
//上記はすべて「不必要な賢い」ことは注目に値します
//明確なスキームを使用して、返された値を比較します
//たとえばindexof:
if(array.indexof( "a")> = 0){
// ...
}
// 3.B.2.3
var num = 2.5;
parseint(num、10);
//に相当します...
~~ num;
num >> 0;
num >>> 0;
//結果はすべて2です
//常に留意してください、負の値は異なって扱われます...
var neg = -2.5;
parseint(neg、10);
//に相当します...
~~否定;
ネグ>> 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
//これを使用することと比較して、参照が真であると判断するだけの場合:
if(foo === true)...
// ...あなたが思うように判断して、組み込みの機能の利点をお楽しみください:
if(foo)...
// 4.1.6
//これを使用することと比較して、参照がfalseであると判断するだけの場合:
if(foo === false)...
// ...感嘆符を使用してtrueに変換します
if(!foo)...
// ...これは0、 ""、null、未定義、ナンに一致することに注意する必要があります
// _must_がブールタイプのfalseである場合、これを使用してください:
if(foo === false)...
// 4.1.7
//参照を計算する場合、それはnullまたは未定義である可能性がありますが、それは偽ではありません、 "または0、
//これを使用することと比較して:
if(foo === null || foo ===未定)...
// ...このような==タイプキャストの利点をお楽しみください:
if(foo == null)...
// ==を使用すると「null」が「null」と「未定」と一致することを忘れないでください
//「false」ではなく、 "、または0
null ==未定義
常に最良かつ最も正確な価値を判断してください。上記は、教義ではなくガイドです。
コードコピーは次のとおりです。
// 4.2.1
//タイプ変換および比較操作の手順
//初めて `===`、 `==`続いた(ゆるいタイプの比較が必要な場合)
// `===`は常にタイプ変換を行うとは限りません。つまり、次のことを意味します。
「1」=== 1;
// 間違い
// `==`タイプを変換します。つまり、次のことを意味します。
「1」== 1;
// 真実
// 4.2.2
// boolean、true&fake
// boolean:
本当、偽
// 本物:
「フー」、1
// pseudo:
""、0、null、未定義、nan、void 0
5。実用的なスタイル
コードコピーは次のとおりです。
// 5.1.1
//実用的なモジュール
(function(global){
var module =(function(){
var data = "secret";
戻る {
//これはブール値です
ブール:本当、
//文字列
文字列:「文字列」、
//配列
配列:[1、2、3、4]、
//オブジェクト
物体: {
ラング:「en-us」
}、
getData:function(){
//「データ」の値を取得します
データを返す;
}、
setData:function(value){
//「データ」の割り当てられた値を返します
return(data = value);
}
};
})();
//他のいくつかがここに表示されます
//モジュールをグローバルオブジェクトに変えます
Global.module = module;
})( これ );
// 5.2.1
//実用的なビルド関数
(function(global){
関数ctor(foo){
this.foo = foo;
これを返します。
}
ctor.prototype.getfoo = function(){
this.fooを返します。
};
ctor.prototype.setfoo = function(val){
return(this.foo = val);
};
//「new」を使用してビルド関数を呼び出すことはありません。これを行うことがあります。
var ctor = function(foo){
新しいctor(foo)を返します。
};
//ビルド関数をグローバルオブジェクトに変えます
Global.ctor = ctor;
})( これ );
6。ネーミング
A.あなたは人間のコンパイラ/コンプレッサーではないので、1つに変換してみてください。
次のコードは、非常に悪い命名の例です。
コードコピーは次のとおりです。
// 6.a.1.1
//悪い命名例コード
関数Q(s){
document.queryselectorall(s)を返します。
}
var i、a = []、els = q( "#foo");
for(i = 0; i <els.length; i ++){a.push(els [i]);}
あなたがそのようなコードを書いたことは間違いありません - それが今日から再び現れないことを願っています。
これは同じロジックを持つコードですが、より堅牢で適切な命名(および読み取り可能な構造)を備えています。
コードコピーは次のとおりです。
// 6.a.2.1
//名前付き例コードを改善しました
function query(selector){
document.queryselectorall(selector)を返します。
}
var idx = 0、
要素= []、
matches = query( "#foo")、
length = matches.length;
for(; idx <length; idx ++){
elemention.push(matches [idx]);
}
いくつかの追加の命名のヒント:
コードコピーは次のとおりです。
// 6.a.3.1
//名前が付けられた文字列
「犬」は文字列です
// 6.a.3.2
//名前配列
`['dogs']`は、「犬の弦」を含む配列です
// 6.a.3.3
//名前関数、オブジェクト、インスタンスなど
Camlcase;機能とvar宣言
// 6.a.3.4
//ビルダー、プロトタイプなどに名前を付けます。
パスカルセ;関数を構築します
// 6.a.3.5
//正規表現に名前を付けます
rdesc = //;
// 6.a.3.6
// Googleクロージャーライブラリスタイルガイドから
functionnameslikethis;
variablenameslikethis;
constructornameslikethis;
Enumnameslikethis;
methodnameslikethis;
symbolic_constants_like_this;
B.これに直面します
よく知られているコールを使用して適用することに加えて、.bind(this)または機能的に同等のものが常に推奨されます。より良いオプションがない場合は、エイリアスを使用して、後続の呼び出しに対して境界機能宣言を作成します。
コードコピーは次のとおりです。
// 6.b.1
function device(opts){
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 = data;
}、 これ) );
setInterval(_。bind(function(){
this.emit( "event");
}、this)、opts.freq || 100);
}
//例:jquery.proxy
function device(opts){
this.value = null;
stream.read(opts.path、jquery.proxy(function(data){
this.value = data;
}、 これ) );
setInterval(jquery.proxy(function(){
this.emit( "event");
}、this)、opts.freq || 100);
}
//例:dojo.hitch
function device(opts){
this.value = null;
stream.read(opts.path、dojo.hitch(this、function(data){
this.value = data;
}));
setinterval(dojo.hitch(this、function(){
this.emit( "event");
})、opts.freq || 100);
}
自己を識別子として、このためのエイリアスを作成する候補者を提供します。これにはバグがある可能性が非常に高いため、可能な限り避ける必要があります。
コードコピーは次のとおりです。
// 6.b.3
function device(opts){
var self = this;
this.value = null;
stream.read(opts.path、function(data){
self.value = data;
});
setInterval(function(){
self.emit( "event");
}、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){
// |これ|今では「obj」です
console.log(this [key]);
}、obj); // < - 最後のパラメーターは `thisarg`です
// 印刷する...
// "foo"
// "バー"
// "qux"
thisargは、array.prototype.every、array.prototype.foreach、array.prototype.some、array.prototype.map、およびarray.prototype.filterで使用できます。
7。その他
この部分が説明するアイデアやアイデアは独断的ではありません。代わりに、一般的なJavaScriptプログラミングタスクを完了するためのより良いソリューションを提供しようとするために、既存のプラクティスに興味があることがより奨励されています。
A.スイッチの使用は避けてください。最新のメソッドトレースは、スイッチ式を使用したブラックリスト機能になります。
FirefoxとChromeの両方が、スイッチステートメントに大幅な改善を行っているようです。 http://jsperf.com/switch-vs-object-literal-vs-module
https://github.com/rwldrn/idiomatic.js/issues/13で改善が見られることは注目に値します。
コードコピーは次のとおりです。
// 7.a.1.1
//声明の例を切り替えます
switch(foo){
ケース「アルファ」:
アルファ();
壊す;
ケース「ベータ」:
ベータ();
壊す;
デフォルト:
//デフォルトのブランチ
壊す;
}
// 7.a.1.2
//組み合わせと再利用をサポートできる方法は、オブジェクトを使用して「ケース」を保存することです。
//関数を使用して代表団を行う:
varケース、委任;
//返品値は説明のみです
ケース= {
アルファ:function(){
// 声明
//返品値
return ["alpha"、arguments.length];
}、
ベータ:function(){
// 声明
//返品値
return ["beta"、arguments.length];
}、
_default:function(){
// 声明
//返品値
return ["default"、arguments.length];
}
};
Delegator = function(){
var args、key、delegate;
//「引数」を配列に変換します
args = [] .slice.call(arguments);
//「引数」から最後の値を抽出します
key = args.shift();
//デフォルトのブランチを呼び出します
Delegate = case._default;
//オブジェクトからメソッドを委任します
if(case.hasownproperty(key)){
DELEGATE = CASE [key];
}
// argの範囲は特定の値に設定できます。
//この場合、| null |大丈夫です
Return Delegate.Apply(null、args);
};
// 7.a.1.3
// 7.a.1.2でAPIを使用します:
委任( "Alpha"、1、2、3、4、5);
// ["alpha"、5]
//もちろん、「ケース」キーの値は任意の値に簡単に変更できます
var casekey、someuserinput;
//何らかの形の入力はありますか?
SOMEUSERINPUT = 9;
if(someuserinput> 10){
casekey = "alpha";
} それ以外 {
casekey = "beta";
}
// または...
casekey = someuserinput> 10? 「アルファ」:「ベータ」;
// それから...
Delegator(CaseKey、SomeUserInput);
// ["ベータ"、1]
//もちろん、これはできます...
Delegator();
// ["デフォルト"、0]
B.事前に値を返すために、パフォーマンスの違いなくコードの読みやすさを向上させる
コードコピーは次のとおりです。
// 7.b.1.1
// 良くない:
function returnLate(foo){
var ret;
if(foo){
ret = "foo";
} それ以外 {
ret = "quux";
}
返品;
}
// 良い:
function returnearly(foo){
if(foo){
「foo」を返します。
}
「QUUX」を返します。
}
8。ネイティブオブジェクトとホストオブジェクト(注:ホストオブジェクトを翻訳すべきではないと常に思っていたので、一般的な執筆方法に従って翻訳します)
最も基本的な原則は次のとおりです。
愚かなことをしないでください、物事は常に良くなります。
この概念を強化するには、このデモをご覧ください。
「すべてが許可されています:ネイティブエクステンション」Andrew Dupont(JSCONF2011、オレゴン州ポートランド)
http://blip.tv/jsconf/jsconf2011-andrew-dupont-everything-is-is-is-extending-built-ins-5211542
9。コメント
最初の選択肢として、シングルラインのコメントがコードの上に配置されます
複数の行は問題ありません
行の最後にあるコメントは避けるべきです!
JSDOCメソッドも良いですが、時間がかかります
10。1つの言語を単独で使用します
プログラムメンテナー(またはチーム)がどの言語に関係なく、プログラムが使用されていることを規定している場合、プログラムは同じ言語でのみ記述する必要があります。
付録
最初にコンマ
このドキュメントを基本スタイルガイドとして使用するすべてのプロジェクトでは、著者が明示的に指定または要求しない限り、コマス前のコード形式を許可しません。