欢迎来到酷客淘商城,为站长提供交易担保服务 访问移动版
站长交易首选担保平台!
酷客淘

前端开发中的一些js规范

日期: 2019-10-17 09:07:21 人气: -

1.不要用遍历器。用JAVAScript高级函数代替`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不要直接调用`Object.prototype`上的方法,如`hasOwnProperty`, `propertyIsEnumerable`, `isPrototypeOf`。


// bad


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


// good


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


3.对象浅拷贝时,更推荐使用扩展运算符[就是`...`运算符],而不是[`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扩展运算符 ...


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.用扩展运算符做数组浅拷贝,类似上面的对象浅拷贝


// 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.用对象的解构赋值来获取和使用对象某个或多个属性值。


// 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.多个返回值用对象的解构,而不是数据解构。


// bad


function processInput(input) {


// 然后就是见证奇迹的时刻


return [left, right, top, bottom];


}


// 调用者需要想一想返回值的顺序


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


// good


function processInput(input) {


// oops, 奇迹又发生了


return { left, right, top, bottom };


}


// 调用者只需要选择他想用的值就好了


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


9. 用命名函数表达式而不是函数声明。


// bad


function foo() {


// ...


}


// bad


const foo = function () {


// ...


};


// good


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


// 函数表达式名和声明的函数名是不一样的


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`操作符`...`去调用多变的函数更好


// 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.当你一定要用函数表达式(在回调函数里)的时候就用箭头表达式吧。


// 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`实现继承


// 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`来实现方法链


// 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.如果没有具体说明,类有默认的构造方法。一个空的构造函数或只是代表父类的构造函数是不需要写的。


// bad


class Jedi {


constructor() {}


getName() {


return this.name;


}


}


// bad


class Rey extends Jedi {


// 这种构造函数是不需要写的


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.三元表达式不应该嵌套,通常是单行表达式。


// 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.避免不需要的三元表达式


// 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` 返回, 那后续的 `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;


}


}