ホームページ > ウェブフロントエンド > jsチュートリアル > フロントエンド JavaScript プログラミング スタイルの簡単な分析

フロントエンド JavaScript プログラミング スタイルの簡単な分析

黄舟
リリース: 2017-03-02 15:24:00
オリジナル
1000 人が閲覧しました

はじめに

多くの企業や団体がスタイル仕様を公開しています。詳細については、jscs.info を参照してください。以下の内容は主に Airbnb の JavaScript スタイル仕様について言及しています。もちろん、Google などからのプログラミングの提案もあります。

プログラミング スタイル

この章では、ES6 の新しい構文を従来の JavaScript 構文と組み合わせて使用​​し、合理的で読みやすく保守しやすいコードを作成する方法について説明します。

プログラミングスタイル

ブロックレベルのスコープ

(1)let は var を置き換えます

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

'use strict';
if (true) {
  let x = 'hello';
}
for (let i = 0; i < 10; i++) {
  console.log(i);
}
ログイン後にコピー

注: 上記のコードで let の代わりに var を使用すると、実際には 2 つのグローバル変数が宣言されますが、これは明らかに意図したものではありません。変数は、変数が宣言されているコード ブロック内でのみ有効である必要があります。var コマンドではこれを行うことはできません。

var コマンドには変数プロモーション効果がありますが、let コマンドにはこの問題はありません:

&#39;use strict&#39;;

if(true) {
  console.log(x); // ReferenceError
  let x = &#39;hello&#39;;
}
ログイン後にコピー

注: 上記のコードで let の代わりに var を使用する場合、console.log 行はエラーを報告しませんが、unknown を出力します。変数宣言はコード ブロックのヘッダーにプロモートされるためです。これは、変数が最初に宣言され、後で使用されるという原則に違反します。


(2) グローバル定数とスレッドセーフ

const は、いくつかの理由から let よりも優れています。 1 つは、const がプログラムを読む人に、この変数は変更すべきではないことを思い出させることができるということ、もう 1 つは、const は関数型プログラミングの考え方に沿ったものであり、その操作は値を変更せず、新しい値を作成するだけであるということです。これは、将来の分散操作にも役立ちます。最後の理由は、JavaScript コンパイラーが const を最適化するため、const をより多く使用すると、プログラムの実行効率が向上するということです。つまり、let と const の本質的な違いは、実際には次のとおりです。コンパイラの内部処理。

// bad
var a = 1, b = 2, c = 3;

// good
const a = 1;
const b = 2;
const c = 3;

// best
const [a, b, c] = [1, 2, 3];
ログイン後にコピー

注: 定数を const として宣言することには 2 つの利点があります。1 つ目は、コードを読む人が値を変更すべきではないことにすぐに気づくことです。2 つ目は、変数値を意図せず変更することによって発生するエラーを防ぐことです。 JavaScript にはマルチスレッド実装がある場合があります (Intel の River Trail プロジェクトなど)。この場合、 let で表される変数は単一のスレッドで実行されるコード内にのみ表示され、複数のスレッドで共有することはできません。これは、スレッドの安全性を確保するのに役立ちます。

文字列

静的文字列では一重引用符またはバックティックを使用する必要があり、二重引用符は使用しないでください。動的文字列ではバッククォートが使用されます。

// bad
const a = "foobar";
const b = &#39;foo&#39; + a + &#39;bar&#39;;
// acceptable
const c = `foobar`;
// good
const a = &#39;foobar&#39;;
const b = `foo${a}bar`;
const c = &#39;foobar&#39;;
ログイン後にコピー

代入の構造化

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

const arr = [1, 2, 3, 4];
// bad
const first = arr[0];
const second = arr[1];
// good
const [first, second] = arr;
ログイン後にコピー

関数のパラメータがオブジェクトのメンバーである場合、構造化代入が優先されます。

// bad
function getFullName(user) {
  const firstName = user.firstName;
  const lastName = user.lastName;
}
// good
function getFullName(obj) {
  const { firstName, lastName } = obj;
}
// best
function getFullName({ firstName, lastName }) {
}
ログイン後にコピー

関数が複数の値を返す場合は、配列の分割代入ではなく、オブジェクトの分割代入を使用します。これにより、後で戻り値を追加したり、戻り値の順序を変更したりすることが容易になります。

// bad
function processInput(input) {
  return [left, right, top, bottom];
}
// good
function processInput(input) {
  return { left, right, top, bottom };
}
const { left, right } = processInput(input);
ログイン後にコピー

Object

単一行で定義されたオブジェクト。最後のメンバーはカンマで終わりません。複数行で定義されたオブジェクトの場合、最後のメンバーはカンマで終わります。

// good
const a = { k1: v1, k2: v2 };
const b = {
  k1: v1,
  k2: v2,
};
ログイン後にコピー

オブジェクトはできる限り静的である必要があり、一度定義したら、新しい属性を自由に追加してはなりません。属性の追加が避けられない場合は、Object.assign メソッドを使用します。

// if reshape unavoidable
const a = {};
Object.assign(a, { x: 3 });

// good
const a = { x: null };
a.x = 3;
ログイン後にコピー

オブジェクトの属性名が動的である場合、オブジェクトの作成時に属性式を使用してそれを定義できます。

// good
const obj = {
  id: 5,
  name: &#39;San Francisco&#39;,
  [getKey(&#39;enabled&#39;)]: true,
};
ログイン後にコピー

配列

拡散演算子 (…) を使用して配列をコピーします。

// bad
const len = items.length;
const itemsCopy = [];
let i;

for (i = 0; i < len; i++) {
  itemsCopy[i] = items[i];
}
// good
const itemsCopy = [...items];
ログイン後にコピー

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

const foo = document.querySelectorAll(&#39;.foo&#39;);
const nodes = Array.from(foo);
ログイン後にコピー

関数

即時実行関数はアロー関数の形式で記述できます。

(() => {
  console.log(&#39;Welcome to the Internet.&#39;);
})();
ログイン後にコピー

関数式を使用する必要がある状況では、代わりにアロー関数を使用してみてください。これはより簡潔であり、これを拘束するためです。

// bad
[1, 2, 3].map(function (x) {
  return x * x;
});
// good
[1, 2, 3].map((x) => {
  return x * x;
});
// best
[1, 2, 3].map(x => x * x);
ログイン後にコピー

Arrow 関数は Function.prototype.bind を置き換えます。これをバインドするために self/_this/that を使用する必要はなくなりました。

// bad
const self = this;
const boundMethod = function(...params) {
  return method.apply(self, params);
}

// acceptable
const boundMethod = method.bind(this);

// best
const boundMethod = (...params) => method.apply(this, params);
ログイン後にコピー

単純で単一行で再利用不可能な関数の場合は、アロー関数を使用することをお勧めします。関数本体が複雑で行数が多い場合は、従来の関数記述方法を使用する必要があります。

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

// bad
function pide(a, b, option = false ) {
}

// good
function pide(a, b, { option = false } = {}) {
}
ログイン後にコピー

関数本体内で引数変数を使用せず、代わりに残り演算子 (…) を使用してください。 REST 演算子はパラメーターを取得することを明示的に示しており、引数は配列のようなオブジェクトであるため、REST 演算子は実数の配列を提供できます。

// bad
function concatenateAll() {
  const args = Array.prototype.slice.call(arguments);
  return args.join(&#39;&#39;);
}

// good
function concatenateAll(...args) {
  return args.join(&#39;&#39;);
}
ログイン後にコピー

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

// bad
function handleThings(opts) {
  opts = opts || {};
}

// good
function handleThings(opts = {}) {
  // ...
}
ログイン後にコピー

マップ構造

現実世界でエンティティ オブジェクトをシミュレートする場合にのみ、オブジェクトを使用します。 key:value データ構造のみが必要な場合は、Map 構造を使用します。 Map にはトラバーサル メカニズムが組み込まれているためです。

let map = new Map(arr);
for (let key of map.keys()) {
  console.log(key);
}
for (let value of map.values()) {
  console.log(value);
}
for (let item of map.entries()) {
  console.log(item[0], item[1]);
}
ログイン後にコピー

Module module

Module 構文は JavaScript モジュールを記述する標準的な方法です。この記述方法に固執してください。 require の代わりに import を使用します。通常の記述方法は次のとおりです:

import { func1, func2 } from &#39;moduleA&#39;;
ログイン後にコピー

module.exports の代わりに export を使用します

// commonJS的写法
var React = require(&#39;react&#39;);

var Breadcrumbs = React.createClass({
  render() {
    return <nav />;
  }
});

module.exports = Breadcrumbs;

// ES6的写法
import React from &#39;react&#39;;

const Breadcrumbs = React.createClass({
  render() {
    return <nav />;
  }
});

export default Breadcrumbs
ログイン後にコピー

モジュールに出力値が 1 つしかない場合は、export default を使用します。 モジュールに複数の出力値がある場合は、export default を使用しないでください。エクスポートのデフォルトを通常のエクスポートと同時に使用します。

モジュール入力にワイルドカードを使用しないでください。これにより、モジュール内にデフォルトの出力 (デフォルトのエクスポート) が存在することが保証されるためです。

import myObject from &#39;./importModule&#39;;
ログイン後にコピー

モジュールがデフォルトで関数を出力する場合、関数名の最初の文字は小文字にする必要があります。これは、キャメルケース名のコーディング スタイルでもあります。

function makeStyleGuide() {}
export default makeStyleGuide;
ログイン後にコピー

如果模块默认输出一个对象,对象名的首字母应该大写。

const StyleGuide = {
  es6: {
  }
};
export default StyleGuide;
ログイン後にコピー

ESLint

ESLint是一个语法规则和代码风格的检查工具,可以用来保证写出语法正确、风格统一的代码。和lint的使用差不多
首先,安装ESLint。

npm i -g eslint
ログイン後にコピー

然后,安装Airbnb语法规则。

npm i -g eslint-config-airbnb
ログイン後にコピー

最后,在项目的根目录下新建一个.eslintrc文件,配置ESLint。

{
  "extends": "eslint-config-airbnb"
}
ログイン後にコピー

比如:

var unusued = &#39;I have no purpose!&#39;;

function greet() {
    var message = &#39;Hello, World!&#39;;
    alert(message);
}

greet();
ログイン後にコピー

然后我们使用命令,就可以检查语法的问题,并给出相关建议。

eslint index.js
ログイン後にコピー
$ eslint index.js
index.js
  1:5  error  unusued is defined but never used                 no-unused-vars
  4:5  error  Expected indentation of 2 characters but found 4  indent
  5:5  error  Expected indentation of 2 characters but found 4  indent

x 3 problems (3 errors, 0 warnings)
ログイン後にコピー

 以上就是前端 JavaScript 编程风格浅析 的内容,更多相关内容请关注PHP中文网(www.php.cn)!

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート