前端開發(fā)中的一些js規(guī)范

1.不要用遍歷器。用JavaScript高級函數(shù)代替`for-in`、 `for-of`。

const numbers = [1, 2, 3, 4, 5];

? ? // bad

? ? let sum = 0;

? ? for (let num of numbers) {

? ? ? sum += num;

? ? }

? ? sum === 15;

? ? // good

? ? let sum = 0;

? ? numbers.forEach(num => sum += num);

? ? sum === 15;

? ? // best (use the functional force)

? ? const sum = numbers.reduce((total, num) => total + num, 0);

? ? sum === 15;

? ? // bad

? ? const increasedByOne = [];

? ? for (let i = 0; i < numbers.length; i++) {

? ? ? increasedByOne.push(numbers[i] + 1);

? ? }

? ? // good

? ? const increasedByOne = [];

? ? numbers.forEach(num => increasedByOne.push(num + 1));

? ? // best (keeping it functional)

? ? const increasedByOne = numbers.map(num => num + 1);

2不要直接調(diào)用`Object.prototype`上的方法,如`hasOwnProperty`, `propertyIsEnumerable`, `isPrototypeOf`。

// bad

? ? console.log(object.hasOwnProperty(key));

? ? // good

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

3.對象淺拷貝時,更推薦使用擴(kuò)展運算符[就是`...`運算符],而不是[`Object.assign`]

// bad

? const original = { a: 1, b: 2 };

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

? // good es6擴(kuò)展運算符 ...

? const original = { a: 1, b: 2 };

? // 淺拷貝

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

? // rest 賦值運算符

? const { a, ...noA } = copy; // noA => { b: 2, c: 3 }

4.用擴(kuò)展運算符做數(shù)組淺拷貝,類似上面的對象淺拷貝

? // bad

? ? const len = items.length;

? ? const itemsCopy = [];

? ? let i;

? ? for (i = 0; i < len; i += 1) {

? ? ? itemsCopy[i] = items[i];

? ? }

? ? // good

? ? const itemsCopy = [...items];

5. 用 `...` 運算符而不是[`Array.from`]

const foo = document.querySelectorAll('.foo');

? ? // good

? ? const nodes = Array.from(foo);

? ? // best

? ? const nodes = [...foo];

6.用對象的解構(gòu)賦值來獲取和使用對象某個或多個屬性值。

// bad

? ? function getFullName(user) {

? ? ? const firstName = user.firstName;

? ? ? const lastName = user.lastName;

? ? ? return `${firstName} ${lastName}`;

? ? }

? ? // good

? ? function getFullName(user) {

? ? ? const { firstName, lastName } = user;

? ? ? return `${firstName} ${lastName}`;

? ? }

? ? // best

? ? function getFullName({ firstName, lastName }) {

? ? ? return `${firstName} ${lastName}`;

? ? }

7. const arr = [1, 2, 3, 4];

? ? // bad

? ? const first = arr[0];

? ? const second = arr[1];

? ? // good

? ? const [first, second] = arr;

8.多個返回值用對象的解構(gòu),而不是數(shù)據(jù)解構(gòu)。

// bad

? ? function processInput(input) {

? ? ? // 然后就是見證奇跡的時刻

? ? ? return [left, right, top, bottom];

? ? }

? ? // 調(diào)用者需要想一想返回值的順序

? ? const [left, __, top] = processInput(input);

? ? // good

? ? function processInput(input) {

? ? ? // oops, 奇跡又發(fā)生了

? ? ? return { left, right, top, bottom };

? ? }

? ? // 調(diào)用者只需要選擇他想用的值就好了

? ? const { left, top } = processInput(input);

9. 用命名函數(shù)表達(dá)式而不是函數(shù)聲明。

// bad

? ? function foo() {

? ? ? // ...

? ? }

? ? // bad

? ? const foo = function () {

? ? ? // ...

? ? };

? ? // good

? ? // lexical name distinguished from the variable-referenced invocation(s)

? ? // 函數(shù)表達(dá)式名和聲明的函數(shù)名是不一樣的

? ? const short = function longUniqueMoreDescriptiveLexicalFoo() {

? ? ? // ...

? ? };

10.不要使用`arguments`,用rest語法`...`代替。

? // bad

? ? function concatenateAll() {

? ? ? const args = Array.prototype.slice.call(arguments);

? ? ? return args.join('');

? ? }

? ? // good

? ? function concatenateAll(...args) {

? ? ? return args.join('');

? ? }

11.用`spread`操作符`...`去調(diào)用多變的函數(shù)更好

? // bad

? ? const x = [1, 2, 3, 4, 5];

? ? console.log.apply(console, x);

? ? // good

? ? const x = [1, 2, 3, 4, 5];

? ? console.log(...x);

? ? // bad

? ? new (Function.prototype.bind.apply(Date, [null, 2016, 8, 5]));

? ? // good

? ? new Date(...[2016, 8, 5]);

12.當(dāng)你一定要用函數(shù)表達(dá)式(在回調(diào)函數(shù)里)的時候就用箭頭表達(dá)式吧。

// bad

? ? [1, 2, 3].map(function (x) {

? ? ? const y = x + 1;

? ? ? return x * y;

? ? });

? ? // good

? ? [1, 2, 3].map((x) => {

? ? ? const y = x + 1;

? ? ? return x * y;

? ? });

13.常用`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;

? ? ? }

? ? }

14. 用`extends`實現(xiàn)繼承

? // bad

? ? const inherits = require('inherits');

? ? function PeekableQueue(contents) {

? ? ? Queue.apply(this, contents);

? ? }

? ? inherits(PeekableQueue, Queue);

? ? PeekableQueue.prototype.peek = function () {

? ? ? return this._queue[0];

? ? }

? ? // good

? ? class PeekableQueue extends Queue {

? ? ? peek() {

? ? ? ? return this._queue[0];

? ? ? }

? ? }

15.可以返回`this`來實現(xiàn)方法鏈

? // bad

? ? Jedi.prototype.jump = function () {

? ? ? this.jumping = true;

? ? ? return true;

? ? };

? ? Jedi.prototype.setHeight = function (height) {

? ? ? this.height = height;

? ? };

? ? const luke = new Jedi();

? ? luke.jump(); // => true

? ? luke.setHeight(20); // => undefined

? ? // good

? ? class Jedi {

? ? ? jump() {

? ? ? ? this.jumping = true;

? ? ? ? return this;

? ? ? }

? ? ? setHeight(height) {

? ? ? ? this.height = height;

? ? ? ? return this;

? ? ? }

? ? }

? ? const luke = new Jedi();

? ? luke.jump()

? ? ? .setHeight(20);

16.如果沒有具體說明,類有默認(rèn)的構(gòu)造方法。一個空的構(gòu)造函數(shù)或只是代表父類的構(gòu)造函數(shù)是不需要寫的。

// bad

? ? class Jedi {

? ? ? constructor() {}

? ? ? getName() {

? ? ? ? return this.name;

? ? ? }

? ? }

? ? // bad

? ? class Rey extends Jedi {

? ? ? // 這種構(gòu)造函數(shù)是不需要寫的

? ? ? constructor(...args) {

? ? ? ? super(...args);

? ? ? }

? ? }

? ? // good

? ? class Rey extends Jedi {

? ? ? constructor(...args) {

? ? ? ? super(...args);

? ? ? ? this.name = 'Rey';

? ? ? }

? ? }

17. 一個路徑只 import 一次。

// bad

? ? import foo from 'foo';

? ? // … some other imports … //

? ? import { named1, named2 } from 'foo';

? ? // good

? ? import foo, { named1, named2 } from 'foo';

? ? // good

? ? import foo, {

? ? ? named1,

? ? ? named2,

? ? } from 'foo';

18. 做冪運算時用冪操作符 `**` 。

? // bad

? ? const binary = Math.pow(2, 10);

? ? // good

? ? const binary = 2 ** 10;

19.三元表達(dá)式不應(yīng)該嵌套,通常是單行表達(dá)式。

? // bad

? ? const foo = maybe1 > maybe2

? ? ? ? "bar"

? ? ? : value1 > value2 ? "baz" : null;

? ? // better

? ? const maybeNull = value1 > value2 ? 'baz' : null;

? ? const foo = maybe1 > maybe2

? ? ? ? 'bar'

? ? ? : maybeNull;

? ? // best

? ? const maybeNull = value1 > value2 ? 'baz' : null;

? ? const foo = maybe1 > maybe2 ? 'bar' : maybeNull;

20.避免不需要的三元表達(dá)式

? // bad

? ? const foo = a ? a : b;

? ? const bar = c ? true : false;

? ? const baz = c ? false : true;

? ? // good

? ? const foo = a || b;

? ? const bar = !!c;

? ? const baz = !c;

21. 如果 `if` 語句中總是需要用 `return` 返回, 那后續(xù)的 `else` 就不需要寫了。 `if` 塊中包含 `return`, 它后面的 `else if` 塊中也包含了 `return`, 這個時候就可以把 `return` 分到多個 `if` 語句塊中。

? // bad

? ? function foo() {

? ? ? if (x) {

? ? ? ? return x;

? ? ? } else {

? ? ? ? return y;

? ? ? }

? ? }

? ? // bad

? ? function cats() {

? ? ? if (x) {

? ? ? ? return x;

? ? ? } else if (y) {

? ? ? ? return y;

? ? ? }

? ? }

? ? // bad

? ? function dogs() {

? ? ? if (x) {

? ? ? ? return x;

? ? ? } else {

? ? ? ? if (y) {

? ? ? ? ? return y;

? ? ? ? }

? ? ? }

? ? }

? ? // good

? ? function foo() {

? ? ? if (x) {

? ? ? ? return x;

? ? ? }

? ? ? return y;

? ? }

? ? // good

? ? function cats() {

? ? ? if (x) {

? ? ? ? return x;

? ? ? }

? ? ? if (y) {

? ? ? ? return y;

? ? ? }

? ? }

? ? // good

? ? function dogs(x) {

? ? ? if (x) {

? ? ? ? if (z) {

? ? ? ? ? return y;

? ? ? ? }

? ? ? } else {

? ? ? ? return z;

? ? ? }

? ? }

摘自https://github.com/airbnb/javascript.git

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容