JS ES6コーディング標準の詳細な説明

JS ES6コーディング標準の詳細な説明

1. ブロックスコープ

1.1. let は var を置き換える

ES6 では、変数を宣言するための 2 つの新しいコマンド、let と const が導入されました。このうち、let は var と同じセマンティクスを持ち、副作用もないため、var を完全に置き換えることができます。

var コマンドには変数昇格の機能がありますが、let にはこのコマンドはありません。

いわゆる変数の昇格とは、変数を最初に使用してから宣言できることを意味します。明らかに、このコーディング標準は読み取りには適していません。

1.2. グローバル定数とスレッドセーフティ

let と const の間では、const を優先します。

let はシングルスレッド モジュール コードで使用する必要がありますが、const はマルチスレッド コードに非常に適しています。

 //悪い
    var a = 1、b = 2、c = 3;

    //良い
    定数a = 1;
    定数b = 2;
    定数 c = 3;

    // 最高
    定数[a, b, c] = [1, 2, 3];

2. 文字列

静的文字列では、常に一重引用符または逆引用符を使用する必要があります。二重引用符は推奨されません。

動的文字列 (文字列テンプレート) ではバックティックが使用されます。

//悪い
定数a = "zhaoyi";
const b = a + "、こんにちは。";

// ちょっと良い
定数 c = `zhaoyi`;

//とても良い
定数a = 'zhaoyi';
const b = `zhaoyi,${a}、私はあなたの名前を2回言います`;

3. 構造化分解割り当て

1. 配列メンバーを使用して変数に値を割り当てる場合は、構造化代入が推奨されます。

const arr = ['私', '愛', 'あなた'];

//悪い
定数1 = arr[0];
定数2 = arr[1];
定数3 = arr[2];

//良い
const [最初、2番目、3番目] = arr;

//テスト
console.log(first, second, third); // 愛しています

2. 関数パラメータがオブジェクトのメンバーである場合は、分解割り当てが優先されます。

//悪い
関数 getUserInfo(ユーザー){
    定数名 = ユーザー名;
    定数 age = user.age;
}

//良い
関数 getUserInfo2(ユーザー){
    const {名前、年齢} = ユーザー;
    console.log(名前、年齢); // 
}

//テスト
getUserInfo2({name: 'zhaoyi', age: 20}); // zhaoyi 20

3. 関数が複数の値を返す場合、配列構造の割り当てよりもオブジェクト構造の割り当てが優先されます。これにより、後から戻り値を追加したり、戻り値の順序を変更したりすることが容易になります。

//悪い
関数 getInfo(入力){
    [左、右]を返します。
}

//良い
関数 getInfo2(入力){
    {left, right} を返します。
}

// ここでは、オブジェクト分解割り当てメソッドを使用して戻り結果を受け取ります。const {left, right} = getInfo2('test');

4. オブジェクト

1. 1 行で定義されたオブジェクトの場合、最後のメンバーはコンマで終わっていません。複数行で定義されたオブジェクトの場合、最後のメンバーはコンマで終わります。

//悪い
定数a1 = {k1: v1、k2: v2、k3: v3、};

//良い 
定数a2 = {k1: v1、k2: v2、k3: v3};

//悪い
定数b1 = {
    k1: v1,
    k2: v2
};

//良い
定数b2 = {
    k1: v1,
    k2: v2,
};

2. オブジェクトはできる限り静的である必要があります。一度定義したら、新しいプロパティを勝手に追加しないでください。プロパティの追加が避けられない場合は、assign メソッドを使用します。

//悪い
定数a = {};
属性 = 3;

// 形状変更が避けられない場合
定数b = {};
オブジェクトに代入(b, {atrr: 3});

//良い
定数 c = {属性: null};
c.attr = 3;

//テスト
console.log(a); //{属性: 3}
console.log(b); //{属性: 3}
console.log(c); //{属性: 3}

3. オブジェクトの属性名が動的(計算によって取得する必要があるという意味)である場合、オブジェクトの作成時に属性式定義を使用できます。 (開発中にこのような状況が発生することはまれです。)

5. 配列

配列をコピーするには、スプレッド演算子 (...) を使用します。

//悪い
関数 copyArr1(arr){
    定数項目コピー = [];
    for (let index = 0; index < arr.length; index++) {
        itemCopy[インデックス] = arr[インデックス];
    }
    itemCopy を返します。
}

//良い
関数 copyArr2(arr){
    [...arr] を返します。
}

//テスト
定数 arr = ['z', 'y', 'z'];
console.log(copyArr1(arr)); // ["z", "y", "z"]
console.log(copyArr2(arr)); // ["z", "y", "z"]

Array.from メソッドを使用して、配列のようなオブジェクトを配列に変換します。

const obj = { "0": "a", "1": "b", 長さ: 2};
配列からオブジェクトを取り出す

//テスト
console.log(arr); // ["a", "b"]

6. 機能

1. 即時実行される関数は、矢印関数の形式で記述できます。

(() => {
    console.log('今夜は良い夜だ。');
})();

2. 関数式が必要な場合は、代わりに矢印関数を使用するようにしてください。より簡潔にまとめることができるからです。

//悪い
const sayHello = ['a', 'b', 'c'].map(function (w){
    'Hello, ' + w を返します。
})

//良い 
const sayHello2 = ['a', 'b', 'c'].map(w => {
    'Hello, ' + w を返します。
});

//テスト
console.log(sayHello2); // ["こんにちは、a", "こんにちは、b", "こんにちは、c"]

3. 矢印関数は Function.prototype.bind に代わるものです。this をバインドするために self/_this/that を使用する必要はなくなりました。

//悪い
const self = this;
const boundMethod = 関数(...パラメータ){
    メソッドを返します。apply(self, params);
}

// 許容できる
const boundMethod2 = method.bind(this);

// 最高
const boundMehod3 = (...params) => method.apply(this, params);

4. 再利用する必要のない 1 行の単純な関数の場合は、矢印関数を使用することをお勧めします。関数本体がより複雑で行数が多い場合は、従来の関数記述方法を使用する必要があります。

5. すべての設定項目は 1 つのオブジェクトに集中し、最後のパラメータに配置する必要があります。ブール値はパラメータとして直接使用できません。

//悪い
関数divide(a, b, オプション = false){

}

//良い
関数divide(a, b, {option = false} = {}){

}

6. 関数本体では引数変数を使用せず、代わりに残り演算子 (...) を使用します。残り演算子は取得したいパラメータを明示的に宣言でき、引数は配列のようなオブジェクトであり、残り要素の理解は実際の配列を提供できるためです。

//悪い
関数f1(){
    const args = Array.prototype.slice.call(引数);
    args.join('-') を返します。
}

//良い
関数 f2(...引数){
    args.join('-') を返します。
}

//テスト
コンソール.log(f1(1, 2, 3)); // 1-2-3
コンソール.log(f2(1, 2, 3)); // 1-2-3

スプレッド演算子は 3 つのドットで表され、その機能は配列または配列のようなオブジェクトをコンマで区切られた一連の値に拡張することです。レスト演算子も 3 つのドットですが、その機能はスプレッド演算子とまったく逆で、コンマで区切られた一連の値を配列に結合します。休息とは残ることを意味します。

7. デフォルト値構文を使用して、関数パラメータのデフォルト値を設定します。

//悪い
関数handleThings(opts){
    opts = opts || {};
    // ...
}

//良い
関数handleThings2(opts = {}){
    // ...
}

7. マップ構造

Map と Object は同じデータ型であるという印象を与えますが、実際のセマンティクスでは、より正確に区別する必要があります。原則は次のとおりです。

  • エンティティ オブジェクトをシミュレートする場合は、Object を使用します。
  • kv キーと値のペアのデータ構造のみが必要な場合は、Map を使用します。

Map には組み込みのトラバーサル メカニズムがあります (Iterator 構造を実装します)

// マップには多くの初期化メソッドがあります。ここでは、2 つの長さを持つ配列が初期化に使用されます (最初の要素は K、2 番目の要素は V)
map = new Map([['k1', 'I'], ['k2', 'love'], ['k3', 'your']]); とします。

// トラバースK
for(const map.keys() のキー){
    console.log(キー);
    // k1
    // k2
    // k3
}

// トラバースV
(map.values() の定数値) {
    console.log(値);
    // 私
    //愛
    // あなた
}

// トラバースKV
(map.entries() の定数項目) {
    console.log(アイテム);
    // ['k1', 'I']
    // ['k2', '愛']
    // ['k3', 'あなたの']
}

8. クラス

1. プロトタイプを必要とする操作の代わりに、常にクラスを使用します。クラスがより簡潔に書かれ、理解しやすくなったからです。 Java や C# に慣れ親しんだ友人は、おそらくこの種のクラス構文を好むでしょう。

//悪い
関数 Queue1(コンテンツ = []){
    this._queue = [...コンテンツ];
}
Queue1.prototype.pop = 関数(){
    定数値 = this._queue[0];
    this._queue.splice(0, 1);
    戻り値;
}

//良い
クラスキュー{
    コンストラクタ(内容 = []){
        // ここで this._queue = contents; を使用しないのはなぜですか?
        // effective Java を読んだことがある友人は、ルールを知っているはずです:
        // つまり、コンストラクタを設計するときに、渡されるパラメータが変数型(オブジェクト、配列)である場合、
        // コンストラクターは、このパラメーターを受け取るときにこのオブジェクトのコピーを使用する必要があります。
        // これにより、外部パラメーター オブジェクトへの変更がクラス自体のインスタンスに影響するのを防ぎます。
        // したがって、ここの内容をコピーして割り当てる必要があります。
        this._queue = [...コンテンツ];
    }
    ポップ() {
        定数値 = this._queue[0];
        this._queue.splice(0, 1);
        戻り値;
    }
}

//テスト
q = 新しいキュー([1, 2, 3]);

console.log(q.pop()); // 1
console.log(q.pop()); // 2
console.log(q.pop()); // 3
console.log(q.pop()); // 未定義

2. 継承を実装するには extends を使用します。これはより単純であり、instanceof 操作を破棄する危険がないためです。

// Queueは前の例のクラスです class PeekQueue extends Queue{
    // ...
}

9. モジュール

1. モジュール構文は js モジュールを記述する標準的な方法なので、これに従う必要があります。 require の代わりに import を使用してください。

//悪い
モジュールAをrequireします。
定数 f1 = ma.f1;
定数 f2 = ma.f2;

//良い
'moduleA' から {f1, f2} をインポートします。

2. module.exportの代わりにexportを使用する

//悪い
モジュールをエクスポートします。

//良い
デフォルトの SomeObj をエクスポートします。

3. モジュールに出力値が 1 つしかない場合は、export default を使用します。chrome がある場合は、export default を使用しないでください。ルールではこの方法でコードを記述できますが、export default と通常の export を同時に使用しないでください。

4. モジュール内でワイルドカードを使用しないでください。ワイルドカードを使用すると、モジュール内にデフォルトのエクスポート (export default) が存在することになります。

//悪い
* を myObject './someModule' としてインポートします。

//良い
'./someModule' から myObject をインポートします。

5. モジュールがデフォルトで関数を出力する場合、関数の最初の文字は小文字にする必要があります。

 関数someFunction(){
     // ...
 }
 デフォルトの someFunction をエクスポートします。

6. モジュールがデフォルトでオブジェクトを出力する場合、オブジェクト名の最初の文字を大文字にする必要があります。

定数someObj = {
    // ...
}
デフォルトの SomeObj をエクスポートします。

10. ESLint

上で挙げた多くのルールは、実はルールテンプレートの氷山の一角に過ぎません。主流メーカーの標準に沿って美しいフォーマットでコードを記述したいのであれば、自分の意識だけに頼るだけでは不十分です。

コードの正確性をチェックするソフトウェア コンパイル ツールと同様に、コードの記述標準をチェックできるソフトウェアはありますか? 答えは「はい」です。

ESLint はそのようなチェックツールです。文法的に正しく、スタイルが一貫したコードが記述されていることを確認するために使用できます。

以下は、ESLink をインストールするためのチュートリアルです (環境に npm がインストールされていることを確認してください)。もちろん、何らかのスキャフォールディング ツール (@vue-cli など) によって生成されたプロジェクトを使用する場合、そのようなプロジェクトはすべてオプションの eslint プラグインを提供します。現在のバージョンは v6.6.0 です。このバージョンの eslint では、より簡単な設定方法が提供されています。設定については、https://eslint.bootcss.com/docs/user-guide/getting-started/ を参照してください。以下は大まかな設定手順です

1. 必要なプラグインをインストールする

$ npm インストール eslint -g

2. package.jsonファイルを生成する

$ npm 初期化

このメソッドは、環境記述ファイルに似た package.json ファイルを現在のディレクトリに生成します。

3. eslint設定ファイルを生成する

$ eslint --init

コマンドは、どのタイプの構成を使用するかを尋ねます(上矢印と下矢印を使用して選択します)

  • json または JavaScript タイプを使用することをお勧めします。ここでは JavaScript タイプの設定ファイルを使用します。
  • スタイルガイドではairbnbを使用します。

必要に応じて他のオプションを選択することもできます。選択が完了すると、必要な依存パッケージが自動的にダウンロードされます。

生成された構成ファイルの内容は次のとおりです。

モジュール.エクスポート = {
  環境: {
    ブラウザ: true、
    es6: 本当、
  },
  拡張: [
    'airbnb-ベース',
  ]、
  グローバル:
    アトミック: '読み取り専用'、
    SharedArrayBuffer: '読み取り専用'、
  },
  パーサーオプション: {
    ecmaバージョン: 2018,
    ソースタイプ: 'モジュール',
  },
  ルール:
  },
};

この設定ファイルで検証ルールを変更することができます。具体的な内容については、上記のリンクを参照してください。

4. 現在のディレクトリにjsファイルを作成する

// インデックス.js
var unused = '灰と幻想のグリムガル';

関数hello(){
    var message = "こんにちは、zhaoyi!";
    アラート(メッセージ);
}
  
こんにちは();

5. eslintでコードの記述の正確さを検証する

$ eslint インデックス.js

1:12 エラー 改行は 'LF' であるはずでしたが、'CRLF' 改行スタイルが見つかりました

2:1 エラー 予期しない var です。代わりに let または const を使用してください。no-var

2:5 エラー 'unused' には値が割り当てられているが、使用されていない no-unused-vars

2:27 エラー 改行は 'LF' であるはずでしたが、'CRLF' 改行スタイルが見つかりました

3:1 エラー 改行は 'LF' であるはずでしたが、'CRLF' 改行スタイルが見つかりました

4:17 エラー 開き括弧の前のスペースがありません space-before-blocks

4:18 エラー 改行は 'LF' であるはずでしたが、'CRLF' 改行スタイルが見つかりました

5:1 エラー 2 スペースのインデントを期待しましたが、4 スペースのインデントが見つかりました

5:5 エラー 予期しない var です。no-var の代わりに let または const を使用してください。

5:19 エラー 文字列にはシングルクォートを使用する必要があります

5:36 エラー 改行は 'LF' であるはずでしたが、'CRLF' 改行スタイルが見つかりました

6:1 エラー 2 スペースのインデントを期待しましたが、4 スペースのインデントが見つかりました

6:5 警告 予期しない警告 警告なし

6:20 エラー 改行は 'LF' であるはずでしたが、'CRLF' 改行スタイルが見つかりました

7:2 エラー 改行は 'LF' であるはずでしたが、'CRLF' 改行スタイルが見つかりました

8:1 エラー 末尾のスペースは許可されません no-trailing-spaces

8:3 エラー 改行は 'LF' であるはずでしたが、'CRLF' 改行スタイルが見つかりました

9:9 エラー 末尾のスペースは許可されません 末尾のスペースなし

9:10 エラー ファイルの末尾に改行が必要ですが見つかりません eol-last

そのうちの 1 つのエラーは、実際には git ファイル形式の変換の問題が原因です。

... 改行スタイル

設定ファイルでこのチェックを削除するには、ルールの下に 'linebreak-style': [0, 'error', 'windows'] を追加します。

ルール:
    '改行スタイル': [0, 'エラー', 'ウィンドウ']
  }

検出コマンドの実行を続けると、次の出力が表示されます。

2:1 エラー 予期しない var です。代わりに let または const を使用してください。no-var

2:5 エラー 'unused' には値が割り当てられているが、使用されていない no-unused-vars

5:1 エラー 2 スペースのインデントを期待しましたが、4 スペースのインデントが見つかりました

5:5 エラー 予期しない var です。no-var の代わりに let または const を使用してください。

5:19 エラー 文字列にはシングルクォートを使用する必要があります

6:1 エラー 2 スペースのインデントを期待しましたが、4 スペースのインデントが見つかりました

6:5 警告 予期しない警告 警告なし

8:1 エラー 末尾のスペースは許可されません no-trailing-spaces

9:9 エラー 末尾のスペースは許可されません 末尾のスペースなし

ご覧のとおり、当社の不規則な操作の多くは警告されます。たとえば、インデントに 4 つのスペースを使用しないでください (実際には、これはコンパイラに組み込まれており、私たちはそれに慣れています)、余分なスペースを追加しないでください、未使用の宣言済み変数を削除してください、var 型の使用は推奨されません、などです。

意味があると思われる場合は、それに従ってください。インデントが習慣に合わないと感じる場合は、設定ファイルを通じてインデントを閉じたり変更したりして、目的の効果を実現することもできます。

以上がJS ES6コーディング標準の詳しい説明です。JS ES6コーディング標準の詳細については、123WORDPRESS.COMの他の関連記事もご覧ください。

以下もご興味があるかもしれません:
  • JavaScript ES6 分割演算子の理解と応用
  • シンプルなカルーセルの最も完全なコード分析を実装するJavaScript(ES6オブジェクト指向)
  • シンプルなショッピングカートの最も完全なコード分析を実装する JavaScript (ES6 オブジェクト指向)
  • JavaScript es6 における var、let、const の違いの詳細な説明
  • JS における ES6 継承と ES5 継承の違い
  • Node.jsがES6モジュールを処理する方法の詳細な説明
  • JSでES6クラスの使い方をすぐにマスター
  • JS ES6 変数分割代入の詳細な説明
  • JS ES6 スプレッド演算子の魔法のような使い方
  • フロントエンドJavaScript ES6の詳細について

<<:  Linuxでpyファイルを直接実行する方法

>>:  select @@session.tx_read_only が DB に大量に出現するのはなぜですか?

推薦する

MySQL データ型における DECIMAL の使用法の詳細な説明

MySQL データ型における DECIMAL の使用法の詳細な説明MySQL のデータ型には、INT...

JSのバイナリファミリーについての簡単な説明

目次概要ブロブBlob の動作BLOB ダウンロード ファイルブロブ画像のローカル表示BLOB ファ...

Nginx Rewriteモジュールを使用するいくつかのシナリオ

アプリケーションシナリオ1: ドメイン名ベースのリダイレクト会社の古いドメイン名は www.accp...

MySQL の自動増分 ID (主キー) が不足した場合の解決策

MySQL で使用される自動インクリメント ID には多くの種類があり、各自動インクリメント ID ...

Excel エクスポートは docker 環境では常に失敗する

Excel のエクスポートは、docker 環境では常に失敗します。最も直接的な原因は、中国語フォン...

VMWare仮想マシンにCentOS7システムをインストールする詳細な手順

インストール前の作業: VMware Workstation がインストールされていることを確認し、...

HTML iframe で親ページと子ページ間の双方向メッセージングを実装する例

ある日、リーダーはメイン ページに iframe を埋め込み、親ページと子ページ間で双方向にメッセー...

Reactコンポーネントのライフサイクルの詳細な説明

目次1.ライフサイクルとは何か2. 読み込みプロセス1.コンストラクタ2. レンダリング3. コンポ...

Docker データボリュームの一般的な操作コードの例

開発者が Dockerfile を使用してイメージをビルドする場合は、イメージをビルドするときにデー...

MySQLが日付フィールドインデックスを使用しない理由の要約

目次背景探検する要約する背景テーブルでは、dataTime フィールドは varchar 型に設定さ...

プログレッシブ ウェブ アプリ (PWA) の開発方法

目次概要必要とするアプリURL PWA にはどのような技術コンポーネントが必要ですか?マニフェストフ...

画像の半透明処理 画像と半透明の背景の実装のアイデアとコード

コードをコピーコードは次のとおりです。 <!DOCTYPE html PUBLIC "...

Linux でアップロードされたファイルのスケジュールされたバックアップと増分バックアップを実装する方法

導入Alibaba Cloud のような OSS ストレージ サービスを使用している場合は、サービス...

MySQLはgroup_concat()関数に基づいて複数のデータ行を結合します

非常に便利な機能group_concat() について、マニュアルには次のように記載されています: ...

数十億のデータに対するMySQLページングの最適化に関する簡単な説明

目次背景分析するデータシミュレーション1. 従業員テーブルと部門テーブルの2つのテーブルを作成します...