よく使うJavaScriptコード規範

6149 ワード

フロントエンドがピットに入る前と後にいくつかの項目を書きました.JavaScriptでインタラクティブロジックを書く時、多かれ少なかれいくつかのごみコードを書きました.例えばグローバル変数汚染、コード多重性が悪く、簡潔性が高くなくて直接コードの後期メンテナンスに困惑をもたらします.以下はJSコードの向上が必要なところです.直接開発に応用して、より優雅なコードの作成に努めます.
コード仕様というと、ESLintルールを思い出すかもしれません.下の仕様はESLintルールに関連して説明されています.ESLintを使う時に関連するエラーメッセージが出てもいいです.
1.変数宣言
1.1 varで変数を宣言しないでください.できるだけconstを使います. 
eslint:prefer-const,no-const-assign
varを使用してグローバル変数の汚染問題を減らすことができることを回避し、constを使用して声明の変数が唯一であることを確認し、これを再割当して操作できない.
		//bad
		var a = 1;
		//best
		const a = 1;
1.2変更可能な引用が必要であれば、varの代わりにletを使用する.
eslint:no-var jscs:disallowVar
letは現在の{}のブロックレベルのスコープに属し、varは関数スコープに属している.
//bad
var count = 1;
if (true) {
	var count = 2;
}
console.log(count)


//best
let count = 1;
if (true) {
	let count = 2;
}
console.log(count)
1.3声明のletとconstをグループ化する
コードの可読性を高めることができます.
//bad
let a = 1;
const obj = {};
let num = 0;
const page = 10;

//best
let a = 1;
let num = 0;
const obj = {};
const page = 10;
1.4 letとconst宣言の変数を適切な位置に置く
letとconstは「一時的なデッドゾーン(Temporal Dead Zons、TDZ)」という概念を与えられているので、彼らが宣言した変数は変数アップグレードされないことになります.var宣言の変数はスコープの上部に引き上げられます.
2.使用対象
2.1文字数を使ってオブジェクトを作成する
eslint:no-new-object
//bad
const obj = new Object();

//good
const obj = {};
2.2対象の方法は略字で書くことです.
// bad
const atom = {
  value: 1,

  addValue: function (value) {
    return atom.value + value;
  },
};

// good
const atom = {
  value: 1,

  addValue(value) {
    return atom.value + value;
  },
};
2.3オブジェクトの属性も略字形式を使用します.
eslint:object-sharthand jscs:require Enhanced Object Literals
const hello = "  ";

//bad
const obj = {
	hello:hello
};

//best
const obj = {
	hello,
};
2.4 Object.prototypeを直接使用しない方法、例えば:hasOwnProperty、propertyIs Enumerable、isPrototypeOfなど
// bad
console.log(object.hasOwnProperty(key));

// good
console.log(Object.prototype.hasOwnProperty.call(object, key));

// best
const has = Object.prototype.hasOwnProperty; // cache the lookup once, in module scope.
const has = require('has');
…
console.log(has.call(object, key));
2.5オブジェクトの浅いコピーが一番いいです.Object.assignではありません.
// very bad
const original = { a: 1, b: 2 };
const copy = Object.assign(original, { c: 3 }); // this mutates `original`
delete copy.a; // so does this

// bad
const original = { a: 1, b: 2 };
const copy = Object.assign({}, original, { c: 3 }); // copy => { a: 1, b: 2, c: 3 }

// good
const original = { a: 1, b: 2 };
const copy = { ...original, c: 3 }; // copy => { a: 1, b: 2, c: 3 }

const { a, ...noA } = copy; // noA => { b: 2, c: 3 }
Object.assignを使うと思わぬ問題が発生します.
3.配列を使う
3.1字面量を使って配列を作成する
eslint:no-array-constructor
// bad
const arr= new Array();

// good
const arr= [];
3.2拡張演算子を使用して、行列をコピーします.
// bad
const arr= new Array();

// good
const arr= [];

// bad
const len = arr.length;
const arrCopy = [];
let i;

for (i = 0; i < len; i++) {
  arrCopy[i] = arr[i];
}

// good
const arrCopy = [...arr];
3.3 Aray.fromを使用して、クラスの配列を配列に変換する
const list = document.getElementsByTagName("li");
const liNodes = Array.from(list);
4.関数
4.1関数宣言を使用して、関数式に代わる表現
なぜですか?関数宣言の関数は、まず識別され、変数の昇格を行います.関数式は、関数の参照変数名を上げるだけです.
// bad
  const fn= function () {
  };

  // good
  function fn() {
  }
4.2もう一つの関数ではないコードブロック(if、else、whileなど)の宣言関数は、  その関数を変数に割り当てます.前者はエラーを出さないとしても、ブラウザの解析方式は違います.
// bad
if (ifLogin) {
  function test() {
    console.log(' logged');
  }
}

// good
let test;
if (ifLogin) {
  test = () => {
    console.log(' logged');
  };
}
4.3アーグメンントの使用を避ける代わりに、restt文法で…
理由はアーグメンントというクラスの配列であり、配列特有の方法がないからです.
// bad
  function myconcat() {
    const args = Array.prototype.slice.call(arguments);
    return args.join('');
  }

  // good
  function myconcat(...args) {
    return args.join('');
  }
5.矢印関数
5.1関数式を使用しなければならない場合(または匿名関数を伝達する必要がある場合)は、矢印関数を使用して代替できます.
新しい関数を使うと新しい関数のスコープが作成されます.このようにして、現在のthisの方向が変わります.矢印関数は新しいthis実行環境を作成して、現在の環境のthisを伝え続けます.そして書き方ももっと簡潔です.
関数が複雑な場合、矢印関数を使うと問題が発生しやすくなります.代わりに関数宣言を使うことができます.
// bad
  [1, 3, 5].map(function (x) {
    return x * x;
  });

  // good
  [1, 3, 5].map((x) => {
    return x * x;
  });
5.2関数が1行で書き出すのに適していて、パラメータが一つしかない場合は、括弧、丸括弧、およびreturnを省略します.もしそうでないなら、省略しないでください.
 // good
  [1, 2, 3].map(x => x * x);

  // good
  [1, 2, 3].reduce((total, n) => {
    return total + n;
  }, 0);
6.コンストラクタ
6.1常にclassを使用し、直接的にprototype属性を操作しない
このように書くのがもっと簡潔です.
// bad
  function Queue(contents = []) {
    this._queue = [...contents];
  }
  Queue.prototype.pop = function() {
    const value = this._queue[0];
    this._queue.splice(0, 1);
    return value;
  }


  // good
  class Queue {
    constructor(contents = []) {
      this._queue = [...contents];
    }
    pop() {
      const value = this._queue[0];
      this._queue.splice(0, 1);
      return value;
    }
  }
7.モジュール開発
7.1モジュールの思想書業務を利用する.
モジュールを使って論理的な業務を作成すると、コードの全体性と拡張性が得られます.似たような倉庫はseaJS、requireJSがあります.
7.2ワイルドカードの使用は少ないです.
このようにして、必要ではないモジュールはimportによってはなく、コードの体積を減らすことができます.
  // bad
  import * as webUI from './WEB';

  // good
  import webUI from './WEB';
8.上位関数を使用して、map()とreduce()をfor~ofの代わりに使用します.
 const arr= [1, 2, 3, 4, 5];

  // bad
  let sum = 0;
  for (let num of arr) {
    sum += num;
  }

  sum === 15;

  // good
  let sum = 0;
  arr.forEach((num) => sum += num);
  sum === 15;

  // best (use the functional force)
  const sum = arr.reduce((total, num) => total + num, 0);
  sum === 15;
9.比較演算子
9.1優先使用==和!==ではなく=と
==と!==強制タイプの変換は行われません.後者は
9.2 if条件判断をする時、強制タイプ変換ルール
  • オブジェクトはtrue
  • に変更されます.
  • null、undefined、NaNはfalse
  • に転送されます.
  • ブール値は対応するブール値
  • に変換される.
  • 数字の中で+0-0はfalseとして計算されます.そうでなければtrue
  • です.
  • 文字列   空の文字列であれば、fasleとして計算されます.そうでなければtrue
  • です.