ES5 JavaScriptガイド


JavaScript品質ガイド


このガイドで提案されているヒントを使用して、開発チームが理解できるコードを作成します。

翻訳者から


こんにちは、マキシム・イワノフ、今日はJavaScriptコードを作成するためルールについてお話します 。 アルゼンチンの開発者であるJavaScript Application Designの著者であるNicolásBevacquaは、このガイドをずっと前に公開しました。最初のレコードは2014年に登場しましたが、今日ではES5規格に従って多くの記述があります。これは、ES6がまだバベルや他のトランスパイラーなしで完全に動作している場所ではないので、依然として関連しています。 計画の70〜90%がすでに実装されているトップエンドのデスクトップブラウザー(Google Crhome、Firefox)で進歩が見られますが、新しい標準のサポートに努めていますが、残念ながらES6を完全にサポートできるブラウザーはありません 。 ところで、私はあなたのコメントをとても喜んでいます。 一般的に、幸運と始めましょう。


はじめに


これらの推奨事項は明確なものではなく、より一貫性があり理解しやすいコードを記述する方法を学ぶのに役立つ基本的なルールです。 提案されたルールを効果的に実行するには、今すぐ開始し、同僚と共有してから運用に移してください。 ただし、これらのルールにこだわるのではなく、実りがなく逆効果になる可能性があります。 誰もがチームで快適に過ごせるように、妥協点を見つけようとします。 コード記述スタイルはすべての人のビジネスであるため、自動化されたコードスタイルチェックは非常に便利です。

内容


  1. モジュール
  2. 厳格モード
  3. スペースのフォーマット
  4. セミコロン
  5. コードスタイル
  6. エラーコード分析
  7. 変数の初期化
  8. 条件付き構造
  9. 比較
  10. 三項演算子
  11. 機能
  12. プロトタイプと継承
  13. オブジェクト
  14. 配列
  15. 正規表現
  16. 開発者コンソール
  17. コメント
  18. 命名
  19. ポリフィルライブラリ
  20. 毎日のトリック
  21. ES6ガイド


モジュール


この項目は、CommonJS、AMD、ES6モジュールなどのモジュラーシステムを使用していることを前提としています。 モジュラーシステムは、グローバルオブジェクトに影響を与えることなく、個別のスコープで動作します。また、依存関係の自動生成により、より体系化されたコード構造を提供し、 <script>タグの自己挿入から解放します。

モジュラーシステムはテンプレートをロードできます。これは、単一の分離されたコンポーネントのテストに関して、ローカルソリューションに役立ちます。

読むには

1. モジュールとは何ですか?
2. CommonJSモジュール
3. JSのモジュール

厳格モード


常に「厳密な使用」を使用します。 モジュールの上部にあります。 ストリクトモードでは言語エラーをキャッチできますが、これは少し怖い名前ですが、このモードではインタープリターがコードの品質を監視できるため、エラーの修正にかかる時間が短縮されます。

読書へ

1. 厳密なディレクティブを使用する
2. 厳密モード

スペースのフォーマット


コードをフォーマットするときにスペースの数を制御します。 このため、 .editorconfig構成ファイルを使用することをお勧めします 。 そのような設定を使用することをお勧めします。

# editorconfig.org root = true [*] indent_style = space indent_size = 2 end_of_line = lf charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true [*.md] trim_trailing_whitespace = false 


タブとスペースの使用はあなた自身の仕事ですが、2つのスペースをインデントすることをお勧めします。 .editorconfigファイルすべてを処理し、Tabキーを押してもフォーマットプロセスは制御されます。

正しいタブだけでなく、適切な場所、たとえば何かの前、後、または間のインデントを調整することもできます。 確かに、これらのことを制御することはかなり面倒な作業です。

 function () {} function( a, b ){} function(a, b) {} function (a,b) {} 

コードのフォーマットの違いを最小限に抑えるようにしてください。

可能であれば、コードの読みやすさを改善し、1行に最大80文字を書き込もうとします。

読書へ:

1. EditorConfig
2. すべてのエディターに1つの設定
3. EditorConfigをSublimeテキスト3にインストールします
4.80- 文字
5. 優れたプログラミングスタイル

セミコロン


ほとんどのJavaScriptプログラマーはセミコロン使用することを好みます 。 自動置換(ASI)を回避するには、セミコロンを常に設定する必要があります。 セミコロンがオプションである言語があり、誰もそこに入れません。 JavaScriptでは、ラインフィードで置き換えられますが、部分的にのみです。したがって、 ASIルールを理解している場合は、改行するのが最善です。

コードに自信があるという事実に関係なく、バリデーター(リンター)を使用して不要なセミコロンをキャッチします。

読書へ:

1. JavaScriptセミコロン挿入
2. コードスタイルのヒント
3. JavaScriptコードの品質を改善する
4. セミコロンについて知る必要があるすべて
5. セミコロンに関するJSリーダーへの公開書簡

コードスタイル


これは気にしないでください。これは、他の分野で同じ厳格なポリシーを順守している間、顕著な成功をもたらさない、非常に苦痛でストレスの多い瞬間です。

もちろん、コード設計(プログラミングスタイル)(英語のコーディング規約)には特定の標準が存在します。 JavaScriptの世界には、この標準であるJSCS(JavaScript Code Style)に準拠しているかどうかコードをチェックするツールさえあります。 共通のプログラミングスタイルを持つことにより、複数のプログラマーによって記述されたソースコードの理解と保守が容易になり、ソフトウェア開発における複数の人々のやり取りが簡素化されます。

このような標準には、プログラマーと最高のチームの両方、および企業全体が含まれます。
1. Airbnb
2. ダグラス・クロックフォード
3. Google
4. グラント
5. 慣用句
6. jQuery
7. MDCS
8. Node.js
9. ウィキメディア
10. ワードプレス
11. ヤンデックス

読書へ:

1. プログラミングスタイル
2. JavaScriptコードスタイル

エラーコード分析


一方、検証が必要な場合があります。 バリデータを使用しない場合は、コードが機能することを確認し、たとえばJSLint(プログラムコードの品質をチェックするためのツール)を使用する必要はありません。 それでも、JSHintまたはESLintの使用をお勧めします。

JSHintを使用するためのヒント:


 { "curly": true, "eqeqeq": true, "newcap": true, "noarg": true, "noempty": true, "nonew": true, "sub": true, "undef": true, "unused": true, "trailing": true, "boss": true, "eqnull": true, "strict": true, "immed": true, "expr": true, "latedef": "nofunc", "quotmark": "single", "indent": 2, "node": true } 


もちろん、これらの規則を厳密に順守する必要はありませんが、バリデータと他のプログラミングスタイルの中間点を見つけることが重要です。

読書へ:

1. JSLint
2. JSHint
3. ESlintを構成するためのいくつかのヒント
4. 崇高なテキスト3でのJSHintの構成
5. JavaScriptリンティング


すべての文字列には、同じタイプの引用符が必要です。 すべてのコードで一重引用符または二重引用符を使用します。
 //  var message = 'oh hai ' + name + "!"; 

 //  var message = 'oh hai ' + name + '!'; 

Node.jsのutil.formatに似たフォーマット関数を使用する場合、これはより速く動作します。 これにより、行の書式設定が簡単になり、コードがずっときれいになります。

 //  var message = util.format('oh hai %s!', name); 

以下のコードを使用して、同様のものを実装できます。
 function format () { var args = [].slice.call(arguments); var initial = args.shift(); function replacer (text, replacement) { return text.replace('%s', replacement); } return args.reduce(replacer, initial); } 

複数行(複数行)を宣言するには、特にHTMLスニペットに関しては、配列をデータバッファーとして使用する方がよい場合があります。データバッファーの要素は、さらに文字列に結合できます。 もちろん、文字列の連結(連結)はおなじみのスタイルではるかに簡単であり、もちろん高速に動作しますが、追跡するのが難しい場合があります。
 var html = [ '<div>', format('<span class="monster">%s</span>', name), '</div>' ].join(''); 

マージした配列に独自のスニペットを挿入し、最後にそれらを結合してコードを読みやすくすることができます。 これが、Jadeなどの一部のテンプレートエンジンの動作方法です。

読書へ:

1.
2. 文字列を使用する
3. 文字列連結のパフォーマンス
4. 型付き配列に基づく文字列のCのような表現

変数の初期化


変数は常に意味と意味で宣言し、スコープの上部で修正します。 各行の変数を個別に初期化してください。 もちろん、 varステートメントを1回宣言し、変数をコンマで区切って指定できますが、プロジェクト全体で一貫性を保つ必要があります。
 //  var foo = 1, bar = 2; var baz; var pony; var a , b; 


 //  var foo = 1; if (foo > 1) { var bar = 2; } 

とにかく、特定の変数が宣言されている場所を正確に見ることができます
 //  var foo = 1; var bar = 2; var baz; var pony; var a; var b; 


 //  var foo = 1; var bar; if (foo > 1) { bar = 2; } 


空の変数は、コンマで区切られた単一行として宣言できます。

 //  var a = 'a'; var b = 2; var i, j; 


条件付き構造


中括弧を使用します。 場合によっては、これにより、SSL / TLSセキュア接続プロトコルの使用中にApple製品の重大なバグを回避できます。

 //  if (err) throw err; 


 //  if (err) { throw err; } 


内容を理解するために、条件ブロックの内容を複数行に維持してください。
 //  if (err) { throw err; } 


読書へ:

1. AppleのSSL / TLSバグ
2. ここでは失敗です

比較


== and!=演算子の使用を避け、より好ましい比較演算子=== and!を使用してください。 ==。 これらの演算子は硬比較演算子と呼ばれますが、代替(==および!=)オペランドを同じデータ型に変換します。

 //  function isEmptyString (text) { return text == ''; } isEmptyString(0); // <- true 


 //  function isEmptyString (text) { return text === ''; } isEmptyString(0); // <- false 


三項演算子


三項演算子は明確に特定の条件に適しており、マルチコンポーネントにはまったく適していません。 一般に、訓練された目が三項演算子の状態を脳がテキストをすぐに読んで解釈できるほど早く見つけられない場合は、三次演算子を使用しないでください。

jQueryは、 厄介な3方向演算子で満たされた代表的例です。

 //  function calculate (a, b) { return a && b ? 11 : a ? 10 : b ? 1 : 0; } 


 //  function getName (mobile) { return mobile ? mobile.name : 'Generic Player'; } 


条件がわかりにくい場合は、単にifおよびelseを使用します

機能


関数を初期化するときは、 関数式の代わりに関数 宣言を使用します 。 これはすべて、変数の「発生」と関数の宣言に影響します。

 //  var sum = function (x, y) { return x + y; }; 


 //  function sum (x, y) { return x + y; } 


カリー化で関数式を使用する場合、関数式に問題はありません

関数の関数宣言も上記のスコープで使用できるため、関数が宣言された順序に関係なく、これはすべて重要です。 原則として、常にグローバルスコープで関数を宣言する必要がありますが、そのような関数を条件ステートメント内に配置しないようにする必要があります。

 //  if (Math.random() > 0.5) { sum(1, 3); function sum (x, y) { return x + y; } } 


 //  if (Math.random() > 0.5) { sum(1, 3); } function sum (x, y) { return x + y; } 


 //  function sum (x, y) { return x + y; } if (Math.random() > 0.5) { sum(1, 3); } 


空の( no-op )メソッドが必要な場合は、 Function.prototypeプロトタイプを使用して拡張機能を使用するか、 関数noop(){} functionを使用できます 。 また、理想的には、アプリケーション全体で使用される独自のメソッドへの参照が1つ必要です。 同じタイプのコード構成を記述する代わりに、メソッドはそのような構成のテンプレートになります。

 //  var divs = document.querySelectorAll('div'); for (i = 0; i < divs.length; i++) { console.log(divs[i].innerHTML); } 


 //  var divs = document.querySelectorAll('div'); [].slice.call(divs).forEach(function (div) { console.log(div.innerHTML); }); 


Function.prototype関数のプロトタイプの.call()関数を使用してバインドを行うことができ、Array.prototype.slice.call()を使用する代わりにレコードを[] .slice.call(引数)に短縮することもできます。 いずれの場合でも、bind()関数を使用して単純化できます。

ただし、このアプローチを使用すると、V8エンジンのパフォーマンスが大幅に低下することに注意してください。

 //  var args = [].slice.call(arguments); 


 //  var i; var args = new Array(arguments.length); for (i = 0; i < args.length; i++) { args[i] = arguments[i]; } 


ループ内で関数を宣言しないでください

 //  var values = [1, 2, 3]; var i; for (i = 0; i < values.length; i++) { setTimeout(function () { console.log(values[i]); }, 1000 * i); } 


 //  var values = [1, 2, 3]; var i; for (i = 0; i < values.length; i++) { setTimeout(function (i) { return function () { console.log(values[i]); }; }(i), 1000 * i); } 


 //  var values = [1, 2, 3]; var i; for (i = 0; i < values.length; i++) { setTimeout(function (i) { console.log(values[i]); }, 1000 * i, i); } 


 //  var values = [1, 2, 3]; var i; for (i = 0; i < values.length; i++) { wait(i); } function wait (i) { setTimeout(function () { console.log(values[i]); }, 1000 * i); } 


または、ループ内の関数のユースケースに最適化された.forEachを使用するだけです。
 //  [1, 2, 3].forEach(function (value, i) { setTimeout(function () { console.log(value); }, 1000 * i); }); 


呼び出しスタックをはるかに簡単に表示するには、匿名関数の使用を減らす必要があります。 つまり、すべてのコールバックを匿名関数として割り当てることに慣れている場合は、それらに名前を付けてみることができます。 これにより、スタックトレースの分析時に例外の根本原因が特定されます。

 //  function once (fn) { var ran = false; return function () { if (ran) { return }; ran = true; fn.apply(this, arguments); }; } 


 //  function once (fn) { var ran = false; return function run () { if (ran) { return }; ran = true; fn.apply(this, arguments); }; } 


関数内のネストされた条件は避けてください。空の戻り値を使用した方が良い場合があります。そのため、コードが読みやすくなります。

 //  function foo (car, black, turbine) { if (car) { if (black) { if (turbine) { return 'batman!'; } } } } 


 //  function fn (condition) { if (condition) { // 10+   } } 


 //  function foo (car, black, turbine) { if (!car) { return; } if (!black) { return; } if (!turbine) { return; } return 'batman!'; } 


関数が何も返さないか、空の戻りを返す場合、 undefinedを返します。

 //  function fn (condition) { if (!condition) { return; } // 10+   } 


読書へ:

1. JavaScriptのスコープと変数および関数宣言の「発生」
2. カレー
3. 空の関数を使用し、jQueryを例として使用します
4. 配列のようなオブジェクト
5. スタックトレース
6. 非同期呼び出しスタックでJavaScriptをデバッグするためのヒント
7. 関数でのJavaScriptの戻り値が未定義を返す

プロトタイプと継承


あらゆるコストで標準プロトタイプを拡張することは避けてください。 言語のネイティブデータ型 (構造)の機能を拡張する必要がある場合は、 ポーザーライブラリを使用するか、データ構造の独自の実装を開発します。

基本的なデータ構造:


プリミティブ値とオブジェクト値を混同しないでください(String、Number、Booleanの場合はtrue)。

 //  String.prototype.half = function () { return this.substr(0, this.length / 2); }; 


 //  function half (text) { return text.substr(0, text.length / 2); } 


プロトタイプ継承モデルはパフォーマンスに影響する可能性があるため、避けてください。 JavaScriptでプログラミングする際のよくある間違いの1つは、基本的なプロトタイプの拡張です。 モンキーパッチングと呼ばれるこの技術は、カプセル化の原則に違反しています。 Prototype.jsなどの広く使用されているフレームワークで使用されているという事実にもかかわらず、現時点ではそれを使用する合理的な理由はありません。 基本プロトタイプを拡張する唯一の正当化は、それらをサポートしない古いバージョンの言語のために、Array.forEachなどの新機能をエミュレートすることだけです。



読書へ:

1. JavaScriptのデータ型とデータ構造
2. データ型の定義
3. プロトタイプとは何ですか?
4. プロトタイプ指向プログラミング
5. 継承とプロトタイプチェーン
6. これ実際のコンテキスト定義とは

オブジェクト


オブジェクトを初期化するには、中括弧{}を使用できます。これはオブジェクトリテラルになります。 純粋なコンストラクターを使用してオブジェクトを作成する代わりに、ファクトリー作成アプローチを使用します。

オブジェクトの作成:
 var World = {}; //  ,       console.log(World); // Object {} 


 var World = { people: "~ 7 .", country: "~ 258 " }; console.log(World); // Object {people: "~ 7 .", country: "~ 258 "} 


カスタムプロトタイプを使用したオブジェクトの作成(コンストラクターの使用へのアプローチ):
 //  // ,   -     var TemplateWorld = function(_people, _country) { //   ,     this       // TemplateWorld        this.people = _people; this.country = _country; } //  (    ) var World = new TemplateWorld("~ 7 .", "~ 258 "); console.log(World); // TemplateWorld {people: "~ 7 .", country: "~ 258 "} 


カスタムプロトタイプを使用したオブジェクトの作成(ファクトリーの使用へのアプローチ):
 //  var TemplateWorld = function(_people, _country) { return { people: _people, country: _country }; } var World = TemplateWorld("~ 7 .", "~ 258 "); console.log(World); // Object {people: "~ 7 .", country: "~ 258 "} 


プロトタイプ作成の良い例:
 //  function util (options) { //      var foo; function add () { return foo++; } function reset () { //  ,       foo = options.start || 0; } reset(); return { //      uuid: add }; } 


参照によるコピーと値渡し

より明確かつ透過的に、メモリセル間でデータが転送される方法は、C / C ++で見ることができます。 しかし、JavaScriptでは、オブジェクトの動作のメカニズムを覚えておくことは非常に望ましいことです。そうすると、いくつかの質問がすぐに消えてしまいます。

変数
 //      //   ,      var a = 'text'; var b = a; //    a = 'update'; console.log(a); // update console.log(b); // text 


オブジェクト
 //      //  JavaScript  c  var a = {foo: 'bar'}; var b = a; //    // b -   a a.foo = 'foo'; console.log(a); // Object {foo: 'foo'} console.log(b); // Object {foo: 'foo'} b.foo = 'bar'; console.log(a); // Object {foo: 'bar'} console.log(b); // Object {foo: 'bar'} 


読書へ:

1. オブジェクト:参照による転送

配列


配列を初期化するには、角括弧[]を使用できます。これは配列のリテラルになります。 パフォーマンスを向上させるために、 新しい配列( length 構造とその長さ(配列のサイズを使用して配列を作成できます。

配列要素を適切に操作するには、標準のメソッドを知る必要があります。 すべてが想像よりもはるかに簡単です。

標準的な方法:


より高度な方法:


リンクでコピー

 //  -     var a = [1, 2, 3]; var b = a; //    // b -   a a[2] = 4; console.log(a); // [1, 2, 4] console.log(b); // [1, 2, 4] b[2] = 3; console.log(a); // [1, 2, 3] console.log(b); // [1, 2, 3] 


標準的な方法の研究を始めましょう:



画像

要素の列挙は.forEachを使用して行われます

これは、JavaScriptで最も簡単な方法の1つです。 IE7およびIE8ではサポートされていません。
コールバック関数を受け入れます。これは、配列内の各要素に対して1回呼び出され、3つの主要な引数を介して渡されます。


さらに、オプションの2番目の引数(オブジェクト、配列、変数など)を渡すことができます。この引数はコールバック関数で使用でき、コンテキスト(this)として表示されます。

 ['_', 't', 'a', 'n', 'i', 'f', ']'].forEach(function (value, index, array) { this.push(String.fromCharCode(value.charCodeAt() + index + 2)) }, out = []) out.join('') // <- 'awesome' 


私たちはだまして、まだ考えていない.joinですが、すぐにこれに到達します。 私たちの場合、配列内のさまざまな要素を組み合わせています。このメソッドは、手動でout [0] + '' + out [1] + '' + out [2] + '' + out [n]するよりもはるかに効率的に機能します。 ところで、breakを使用した通常の反復で行われるように、foreachループを中断することはできません。 幸いなことに、他の方法があります。

.someおよび.everyでチェックします

これらのメソッドは、アサート関数に関連しています。 .NETで列挙型を使用したことがある場合は、それらがいとこである.Any(x => x.IsAwesome)および.All(x => x.IsAwesome)に似ていることがわかります。

これらのメソッドは、同じ引数を持つコールバック関数も受け入れるという点で.forEachに似ていますが、性質がわずかに異なります。

some()メソッドは、コールバックがtrue値(ブール型にキャストされたときにtrueになる値)を返す要素が見つかるまで、配列に存在する各要素に対して渡されたコールバック関数を1回呼び出します。 そのような要素が見つかった場合、some()メソッドはすぐにtrueを返します。 そうでない場合、コールバックが配列のすべての要素に対してfalseを返すと、some()メソッドはfalseを返します。 コールバック関数は、値が割り当てられた配列インデックスに対してのみ呼び出されます。 削除されたインデックス、または値が割り当てられていないインデックスに対しては呼び出されません。

 max = -Infinity satisfied = [10, 12, 10, 8, 5, 23].some(function (value, index, array) { if (value > max) max = value return value < 10 }) console.log(max) // <- 12 satisfied // <- true 


.every()メソッドも同じように機能しますが、クロージャーはコールバック関数が偽ではなく偽を返したときにのみ発生します。

.joinおよび.concatとマージ

ご存知のように、.joinメソッドは.concatメソッドと混同されることがよくあります。このメソッドは引数.join(セパレーター)にセパレーターを取り、ストリングを作成します。その結果、配列の各要素を取り、そのストリング内のセパレーターでそれらを区切ります。 区切り文字が指定されていない場合、デフォルトでは区切り文字= '、'になります。 concat()メソッドは、呼び出された配列、他の配列に接続された配列、および/または引数として渡された値で構成される新しい配列を返します。



不完全なコピーとは、コピーに元の配列と同じオブジェクト参照が含まれることを意味します。
原則として、元の配列と新しい配列の両方が同じオブジェクトを参照します。
つまり、参照によってオブジェクトが変更された場合、新しい配列と元の配列の両方で変更が表示されます。

 var a = { foo: 'bar' } var b = [1, 2, 3, a] var c = b.concat() console.log(b === c) // <- false a.foo = 'foo'; console.log(b); // [1, 2, 3, Object {foo: 'foo'}] console.log(c); // [1, 2, 3, Object {foo: 'foo'}] b[3] === a && c[3] === a // <- true 


.pop、.push、.shift、および.unshiftを使用してスタックとキューを操作します

現在、配列の末尾への要素の追加は.pushを使用して行われることを誰もが知っています。そして、この構造[] .push( 'a'、 'b'、 'c'、 'd'、 'z')を使用して、一度に複数の要素を追加できますか?

 var a = [].push('a', 'b', 'c', 'd', 'z'); console.log(a); // 5 

 var a = []; a.push('a', 'b', 'c', 'd', 'z'); console.log(a); // ['a', 'b', 'c', 'd', 'z'] 


pop()メソッドは、配列から最後の要素を削除し、その値を返します。配列が空の場合、undefined(void 0)が返されます。

.pushと.popを使用して、独自のLIFOスタック構造を開発できます。

 function Stack () { this._stack = [] } Stack.prototype.next = function () { return this._stack.pop() } Stack.prototype.add = function () { return this._stack.push.apply(this._stack, arguments) } stack = new Stack() stack.add(1, 2, 3) stack.next() // <- 3 stack.next() // <- 2 stack.next() // <- 1 stack.next() // <- undefined 


逆に、.unshiftと.shiftを使用してFIFOキューを作成できます。

 function Queue () { this._queue = [] } Queue.prototype.next = function () { return this._queue.shift() } Queue.prototype.add = function () { return this._queue.unshift.apply(this._queue, arguments) } queue = new Queue() queue.add(1,2,3) queue.next() // <- 1 queue.next() // <- 2 queue.next() // <- 3 queue.next() // <- undefined 


配列要素のセットのループで.shift(または.pop)を使用すると、プロセスでそれをクリアできます。

 list = [1,2,3,4,5,6,7,8,9,10] while (item = list.shift()) { console.log(item) } list // <- [] 


反復メソッド(マッピング).map

map()メソッドは、配列の各要素に対して指定された関数を呼び出した結果で新しい配列を作成します。

mapメソッドは、渡されたコールバック関数を要素ごとに1回ずつ呼び出して、呼び出しの結果から新しい配列を構築します。コールバック関数は、未定義を含む値が割り当てられた配列インデックスに対してのみ呼び出されます。不足している配列要素(つまり、設定されていないインデックス、削除されたインデックス、または値が割り当てられていないインデックス)に対しては呼び出されません。

Array.prototype.mapメソッドには、.forEach、.some、.everyと同じシグネチャがあります。.map
(fn(値、インデックス、配列)、thisArgument)。

 values = [void 0, null, false, ''] values[7] = 'text' result = values.map(function(value, index, array){ console.log(value) return value }) // <- [undefined, null, false, '', undefined × 3, undefined] console.log(result[7]); // text 


undefined×3-削除または割り当てられていない配列の要素に対して.mapメソッドが機能しなかったが、結果の配列に含まれていることを説明しています。.mapメソッドは、配列の変換に使用されます。

 //  [1, '2', '30', '9'].map(function (value) { return parseInt(value, 10) }) // 1, 2, 30, 9 [97, 119, 101, 115, 111, 109, 101].map(String.fromCharCode).join('') // <- 'awesome' //       items.map(function (item) { return { id: item.id, name: computeName(item) } }) 


.filterリクエストの実行

filter()メソッドは、渡された関数で指定されたテストに合格したすべての要素を含む新しい配列を作成します。

filter()メソッドは、配列に存在する各要素に対して渡されたコールバック関数を1回呼び出し、コールバック関数がtrueを返したすべての値またはブール値にキャストされたときにtrueになる値で新しい配列を作成します。コールバック関数は、値が割り当てられた配列インデックスに対してのみ呼び出されます。削除されたインデックス、または値が割り当てられていないインデックスに対しては呼び出されません。コールバック関数に失敗した配列要素は単にスキップされ、新しい配列には含まれません。

通常どおり:.filter(fn(値、インデックス、配列)、thisArgument)。.filterがコールバック関数のチェックに合格した要素のみを返すことを考えると、いくつかの興味深い使用例があります。

 [void 0, null, false, '', 1].filter(function (value) { return value }) // <- [1] [void 0, null, false, '', 1].filter(function (value) { return !value }) // <- [void 0, null, false, ''] 


.sortで並べ替え

sort()メソッドは、配列の要素をその場でソートし、ソートされた配列を返します。ソートは必ずしも安定しているとは限りません。デフォルトのソート順は、Unicodeコードポイントの順序に対応しています。

シグネチャはほとんどのソート関数と同じです:Array.prototype.sort(fn(a、b))、メソッドは2つの要素をチェックするコールバックを受け入れます。その結果、タスクに応じて、戻り値は次のようになります。



 [9,80,3,10,5,6].sort() // <- [10, 3, 5, 6, 80, 9] [9,80,3,10,5,6].sort(function (a, b) { return a - b }) // <- [3, 5, 6, 9, 10, 80] 


.reduce、.reduceRightによる計算

reduce()メソッドは、voidsを除き、配列に存在する各要素に対してコールバック関数を1回実行します。4つの引数を取ります:初期値(または前のコールバック呼び出しからの値)、現在の要素の値、現在のインデックス、および反復された配列。

一般に、reduce()メソッドとreduceRight()メソッドは同一です。ただし、reduce()メソッドの要素の列挙は左から右に、reduceRight()メソッドでは右から左になります。

両方のメソッドには、次のシグネチャがあります:reduce(コールバック(previousValue、currentValue、index、array)、initialValue)。

関数が初めて呼び出されたとき、previousValueパラメーターとcurrentValueパラメーターは2つの値のいずれかを取ることができます。reduce()が呼び出されたときにinitialValue引数が渡された場合、previousValue値はinitialValue値と等しくなり、currentValue値は配列の最初の値と等しくなります。initialValue引数が指定されていない場合、previousValue値は配列の最初の値に等しくなり、currentValueは配列の2番目の値に等しくなります。

.reduce sum関数の典型的な使用例の1つは次のとおりです。
 Array.prototype.sum = function () { return this.reduce(function (partial, value) { return partial + value }, 0) }; [3,4,5,6,10].sum() // <- 28 


複数の行を連結したいとします。この目的で.joinを使用できます。しかし、オブジェクトの場合、これは機能しません。したがって、
 function concat (input) { return input.reduce(function (partial, value) { if (partial) { partial += ', ' } return partial + value.name }, '') } concat([ { name: 'George' }, { name: 'Sam' }, { name: 'Pear' } ]) // <- 'George, Sam, Pear' 


.sliceでコピー

.concatと同様に、引数なしで.sliceを呼び出すと、元の配列の不完全なコピーが生成されます。この関数は、開始位置と終了位置の2つの引数を取ります。Array.prototype.sliceを使用して、配列をオブジェクトに、またはその逆を配列に変換できます。

 Array.prototype.slice.call({ 0: 'a', 1: 'b', length: 2 }) // <- ['a', 'b'] 


ただし、これは.concatでは機能しません。
 Array.prototype.concat.call({ 0: 'a', 1: 'b', length: 2 }) // <- [{ 0: 'a', 1: 'b', length: 2 }] 


さらに、.sliceメソッドを使用する別の一般的な方法は、引数リストから複数のアイテムを削除することです。
 function format (text, bold) { if (bold) { text = '<b>' + text + '</b>' } var values = Array.prototype.slice.call(arguments, 2) values.forEach(function (value) { text = text.replace('%s', value) }) return text } format('some%sthing%s %s', true, 'some', 'other', 'things') // <- <b>somesomethingother things</b> 


.splice要素を削除および追加するためのより強力なツール

splice()メソッドは、既存の要素を削除したり、新しい要素を追加したりして、配列の内容を変更します。指定された挿入要素の数が削除された要素の数と異なる場合、配列は呼び出し後に長さを変更します。.concatや.sliceとは異なり、この関数は元の配列を変更することに注意してください。

 var source = [1,2,3,8,8,8,8,8,9,10,11,12,13] var spliced = source.splice(3, 4, 4, 5, 6, 7) console.log(source) // <- [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 ,13] spliced // <- [8, 8, 8, 8] 


削除されたアイテムを返すことも既に言及されている可能性があり、これが役立つ場合があります。
 var source = [1,2,3,8,8,8,8,8,9,10,11,12,13] var spliced = source.splice(9) spliced.forEach(function (value) { console.log('removed', value) }) // <- removed 10 // <- removed 11 // <- removed 12 // <- removed 13 console.log(source) // <- [1, 2, 3, 8, 8, 8, 8, 8, 9] 


.indexOf配列内のアイテムを検索する

indexOf()メソッドは、厳密な比較を使用して、検索されたsearchElementと配列内の要素を比較します(===演算子で同じメソッドが使用され、トリプルが使用されます)。

 var a = { foo: 'bar' } var b = [a, 2] console.log(b.indexOf(1)) // <- -1 console.log(b.indexOf({ foo: 'bar' })) // <- -1 console.log(b.indexOf(a)) // <- 0 console.log(b.indexOf(a, 1)) // <- -1 b.indexOf(2, 1) // <- 1 b.indexOf(2, a) // <- 1 b.indexOf(a, 2) // <- -1 


in演算子を支援するには

初心者がインタビューに対してよくある間違いは、.indexOfメソッドとin演算子の同じ操作に関する混乱した意見です。
 var a = [1, 2, 5] 1 in a // <- true //     a[1],   2! 5 in a // <- false //   a[5]   


実際、in演算子ではオブジェクトのキーをチェックし、値で検索しません。このオプションは、.indexOfを使用する場合よりもはるかに高速に機能します。

 var a = [3, 7, 6] 1 in a === !!a[1] // <- true 


逆順での反復、または.reverseを使用した配列の反転

このメソッドは、配列内の要素を取得し、それらを逆の順序で配置します。

 var a = [1, 1, 7, 8] a.reverse() // [8, 7, 1, 1] 


読むには:

1. アレイ
2. アレイvs. 対象
3. JavaScriptでの配列のパフォーマンス
4. 配列の高速化
5. JavaScriptでのオブジェクト/配列のパフォーマンス
6. メソッドの列挙
7. 配列、オブジェクト、および関数を操作するための追加機能を実装するライブラリ

正規表現


正規表現は、正規表現リテラルである2つのスラッシュ/ /を使用して作成されます内部で検索パターンを指定します。正規表現を変数に保存するようにしてください。コードに直接(インラインで)埋め込まないでください。これにより、読みやすさが大幅に向上します。

 //  if (/\d+/.test(text)) { // non-precompiled, but faster console.log('so many numbers!'); } 


 //  var numeric = /\d+/; // precompiled if (numeric.test(text)) { console.log('so many numbers!'); } 


さらに、正規表現の書き方を学び、それらが必要な理由を見つけることができます。オンラインで見ることで視覚化することもできます

読むには:

1. 正規表現
2. RegExpクラス
3. 文字列の検索および置換 メソッド
4. RegExpおよびStringメソッド
5. JavaScriptプリコンパイルされた正規表現のパフォーマンス
6. 基本的な概念とパフォーマンスの問題
7. 通常のvarazheniyamiで作業するためのタスク

開発者コンソール


Webアプリケーションのステータスを確認するには、後で運用中に削除できるコンソールオブジェクトを使用すると非常に便利です。この機能は標準ではなく、まだ標準化する予定はありません。また、実装間に大きな非互換性がある場合があり、その動作は将来変更される可能性があります。したがって、サイトで使用して、コードをインターネットに投稿しないでください。Webアプリケーションをデバッグするとき、すべてを出力ログ(console.logに書き込まないようにしてください。

読むには:

1. 初心者向けのJavaScriptのデバッグ
2. コンソールの使用
3. 呼び出しスタック。トレース
4. Chromeの真実。Web Inspector
5. ChromeコンソールAPI

コメント


コメントは、コードの機能を説明することを目的としていません。良いコードはそれ自体を語るべきです。コードの一部が何をするのかを説明したい場所にコメントを書くことを考えている場合は、おそらくコード自体を変更する必要があります。この規則の例外は、正規表現のような構文構成要素がロードされたコードの複雑なセクションの説明です。良いコメントは、コードの一部がそのように機能する理由とその特定の目的が何であるかを説明する必要があります。

 //  //    var p = $('<p/>'); p.center(div); p.text('foo'); 

 //  var container = $('<p/>'); var contents = 'foo'; container.center(parent); container.text(contents); megaphone.on('data', function (value) { container.text(value); // megaphone      }); var numeric = /\d+/; if (numeric.test(text)) { console.log('so many numbers!'); } 


バージョン管理システムがあるので、コードの巨大なブロックについてコメントしないでください!

読むには:

1. 超可読コードを書くための16のコツ
2. コードにコメントするためのベストプラクティス
3. 関数にコメントする
4. JavaScriptドキュメントのジェネレーター

命名


変数には意味のある名前が必要です。このコードの一部を理解するために、コメントやドキュメントを読むことに頼る必要はありません。

 //  function a (x, y, z) { return (x+y+z) / 3; } a(1, 3, 5); // <- 3 


 //  function average(a, b, c) { return (a + b + c) / 3; } average(1, 3, 5); // <- 3 


読むには:

1. JavaScriptスタイルガイドとコーディング規則

ポリフィルライブラリ


ネイティブのブラウザー機能を使用できない場合、つまり、デフォルトでは実装されていない場合は、古いブラウザーでこれらの機能をサポートするために必要な動作をエミュレートするポリフィルライブラリを含めます。その結果、コードを簡単に操作できるようになりました。安定性を維持するために条件付きの構造や他の構造を重ねる必要がなくなりました。

ポリフィルライブラリの機能が不足している場合は、そのようなライブラリ用のプラグインを作成するか、ポリフィルでラップすることで標準機能とオブジェクトの機能を単純に拡張できます。

読むには:

1. 最新のDOM:ポリフィル
2. 10種類の最高のポリフィルライブラリ
3. 既製のポリフィルライブラリのリスト

毎日のトリック


1.論理演算子||を使用します デフォルト値を決定します。演算子の左側の値がfalseの場合、演算子の右側の値が使用されます(false || true)。false、0、null、または ''などの値の弱い型比較のため、論理演算子に関して右側に指定したデフォルト値が使用されることに注意してください。厳密な型チェックには、次の構成を使用します。if(value === void 0){value = defaultValue}

 function a (value) { var defaultValue = 33; var used = value || defaultValue; } 


2. 関数を部分的に使用するには、.bindメソッドを使用できます
 function sum (a, b) { return a + b; } var addSeven = sum.bind(null, 7); addSeven(6); // <- 13 


3. オブジェクトから配列を取得する場合は、Array.prototype.slice.callを使用します
 var args = Array.prototype.slice.call(arguments); 


4. あらゆることにイベントリスナー使用します。
 var emitter = contra.emitter(); // example, event emitters: jQuery, Angular, React .. body.addEventListener('click', function () { emitter.emit('click', e.target); }); emitter.on('click', function (elem) { console.log(elem); }); //   emitter.emit('click', document.body); 


5.空の関数(no-op)が必要な場合は、Function()を使用します
 function (cb) { setTimeout(cb || Function(), 2000); } 


読むには:

1. browserhacks
2. 5人気のJavaScriptハック
3. 流行に敏感ないくつかのJavaScriptハック
4. イベントの作成と呼び出し
5. JavaScriptマジック:引数

ES6ガイド


JavaScriptはECMA(W3Cなど)によって標準化されており、その標準はECMAScriptと呼ばれています。ECMAScriptは次を定義します。



2009年に、ES5は正式に完成し(2011年のES5.1以降)、Firefox、Chrome、Opera、Safariなどのブラウザーの広範な標準になりました。次のバージョンのJS(2013年、2014年、2015年)を待っている中で、最も議論された新しいブランチはES6でした。

ES6は根本的な進歩です。JS(ES5)を知っていると思われる場合でも、ES6にはまだ学習しなければならない新しいことがたくさんあります。準備をしなさい!ES6はまったく異なります。これは、長年にわたるよく調整された作業の結果です。そして、これは新しい言語機能の宝物です。これまでで最も重要なJSアップデート。新しい機能は、矢印関数や線補間などの単純な機能から、プロキシやジェネレーターなどの脳を爆発させる概念にまで及びますが、今では探索を開始できます(以下の文献のリンクを参照)。

読むには:

1. ES6のモダンスタイルガイド
2. ES6のチートシート
3. ES6 について学ぶ必要があるすべて
4. ES6の詳細: はじめに
5. ES6以降
6. ECMAScriptの例6
7. ES6の350の側面

Source: https://habr.com/ru/post/J281110/


All Articles