May 08, 2021 ES6
(1) let replaces var
ES6 presents commands for two new declaration
let
const
Where,
let
completely replace
var
because the two semantics are the same, and let
let
side effects.
'use strict';
if (true) {
let x = 'hello';
}
for (let i = 0; i < 10; i++) {
console.log(i);
}
If the above code replaces let with var, it actually declares two global variables, which is obviously not the intention. Variables should only be valid within the block of code they declare, as the var command does not do.
The var command has a variable boost utility, and the let command does not have this problem.
'use strict';
if (true) {
console.log(x); // ReferenceError
let x = 'hello';
}
If the above code replaces let with var, console.log the line will not report an error, but will output undefined because the variable declaration is promoted to the head of the block. This violates the principle that variables are declared and then used.
Therefore, it is recommended that you no longer use the var command, but instead use the let command instead.
(2) Global constant and thread safety
Between
let
and
const
is recommended that
const
used first, especially in global environments, where variables should not be set, only constants should be set.
Const is better than let for several reasons. O ne is that const can remind the reader that this variable should not be changed; the other is that const is more in line with the functional programming idea, the operation does not change the value, only the new value, and this is also conducive to future distributed operations; and the last reason is that the JavaScript compiler optimizes the const, so use more const, which is conducive to improving the efficiency of the program, that is, the essential difference between let and const, In fact, the handling inside the compiler is different.
// 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 declares that there are two other benefits to constants: that people who read the code immediately realize that this value should not be modified, and that they prevent errors caused by inadvertently modifying variable values.
All functions should be set to constant.
In the long run, JavaScript may have a multithreaded implementation (such as a project like Intel's River Trail), where let represents variables that should only appear in single-threaded code and not be multithreaded, which helps ensure thread safety.
Static strings use single or back quotes, not double quotes. Dynamic strings use back quotes.
// bad
const a = "foobar";
const b = 'foo' + a + 'bar';
// acceptable
const c = foobar ;
// good
const a = 'foobar';
const b = foo${a}bar ;
Deconstructing assignments is preferred when assigning variables using array members.
const arr = [1, 2, 3, 4];
// bad
const first = arr[0];
const second = arr[1];
// good
const [first, second] = arr;
The arguments of the function, if they are members of an object, take precedence over deconstruction assignments.
// 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 }) {
}
If the function returns more than one value, the deconstruction assignment of the object is preferred over the deconstruction assignment of the array. This makes it easier to add return values later and change the order in which they are returned.
// bad
function processInput(input) {
return [left, right, top, bottom];
}
// good
function processInput(input) {
return { left, right, top, bottom };
}
const { left, right } = processInput(input);
A single-line defined object, and the last member does not end with a comma. A multi-line defined object, with the last member ending with a comma.
// bad
const a = { k1: v1, k2: v2, };
const b = {
k1: v1,
k2: v2
};
// good
const a = { k1: v1, k2: v2 };
const b = {
k1: v1,
k2: v2,
};
Objects are as static as possible, and once defined, no new properties can be added at will.
If adding properties is unavoidable, use
Object.assign
method.
// bad
const a = {};
a.x = 3;
// if reshape unavoidable
const a = {};
Object.assign(a, { x: 3 });
// good
const a = { x: null };
a.x = 3;
If the property name of an object is dynamic, you can define it using a property expression when you create an object.
// bad
const obj = {
id: 5,
name: 'San Francisco',
};
obj[getKey('enabled')] = true;
// good
const obj = {
id: 5,
name: 'San Francisco',
[getKey('enabled')]: true,
};
In the code above, the last property name of the object obj needs to be calculated. I t is a good idea to use a property expression that is defined with other properties when a new obj is created. That way, all the properties are defined in one place.
In addition, the properties and methods of the object, as far as possible, the use of concise expression, so that easy to describe and write.
var ref = 'some value';
// bad
const atom = {
ref: ref,
value: 1,
addValue: function (value) {
return atom.value + value;
},
};
// good
const atom = {
ref,
value: 1,
addValue(value) {
return atom.value + value;
},
};
Using the extension operator (... Copy the array.
// bad
const len = items.length;
const itemsCopy = [];
let i;
for (i = 0; i < len; i++) {
itemsCopy[i] = items[i];
}
// good
const itemsCopy = [...items];
Use the Array.from method to convert array-like objects into arrays.
const foo = document.querySelectorAll('.foo');
const nodes = Array.from(foo);
Executing a function immediately can be written as an arrow function.
(() => {
console.log('Welcome to the Internet.');
})();
For those cases where anonymous functions are used as arguments, try to replace them with arrow functions. Because it's more concise, and it's tied to this.
// 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);
The arrow function
Function.prototype.bind
and should no longer bind this _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);
Simple, single-line, reusable functions, with arrow functions recommended. If the function body is more complex and has more rows, the traditional function writing method should be used.
All configuration items should be concentrated in one object, placed in the last argument, and boolean values should not be used directly as parameters.
// bad
function divide(a, b, option = false ) {
}
// good
function divide(a, b, { option = false } = {}) {
}
Do not use the arguments variable in the body of the function, use the rest operator (... I nstead. Because the rest operator explicitly indicates that you want to get arguments, and arguments is an array-like object, the rest operator can provide a real array.
// bad
function concatenateAll() {
const args = Array.prototype.slice.call(arguments);
return args.join('');
}
// good
function concatenateAll(...args) {
return args.join('');
}
Use the default syntax to set the default values for function parameters.
// bad
function handleThings(opts) {
opts = opts || {};
}
// good
function handleThings(opts = {}) {
// ...
}
Note that objects and Maps are distinguished and are used only when simulating real-world entity objects. I
f you just need
key: value
data structure, use the Map structure.
Because Map has a built-in traversal mechanism.
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]);
}
Always replace the operation that requires prototype with Class. Because Class is written more concisely and more easily understood.
// 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;
}
}
Inheritance
extends
using extends because it is simpler and there is no risk of
instanceof
operation.
// 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];
}
}
First,
Module
syntax is the standard way to write JavaScript modules, and you stick to it.
Use
import
require
// bad
const moduleA = require('moduleA');
const func1 = moduleA.func1;
const func2 = moduleA.func2;
// good
import { func1, func2 } from 'moduleA';
Use export instead of module.exports.
// commonJS的写法
var React = require('react');
var Breadcrumbs = React.createClass({
render() {
return <nav />;
}
});
module.exports = Breadcrumbs;
// ES6的写法
import React from 'react';
class Breadcrumbs extends React.Component {
render() {
return <nav />;
}
};
export default Breadcrumbs;
If the module has only one output value,
export default
if the module has more than one output value,
export default
export default
normal export do not
export
the same time.
Do not use wildcards in module inputs. Because this ensures that there is a default output (export default) in your module.
// bad
import * as myObject from './importModule';
// good
import myObject from './importModule';
If the module outputs a function by default, the initials of the function name should be lowercase.
function makeStyleGuide() {
}
export default makeStyleGuide;
If the module outputs an object by default, the initials of the object name should be capitaled.
const StyleGuide = {
es6: {
}
};
export default StyleGuide;
ESLint
syntax rule and code style checking tool that can be used to ensure that code with correct syntax and uniform style is written.
First, install ESLint.
$ npm i -g eslint
Then, install Airbnb syntax rules, as well as import, a11y, react plug-ins.
$ npm i -g eslint-config-airbnb
$ npm i -g eslint-plugin-import eslint-plugin-jsx-a11y eslint-plugin-react
Finally, create a new .eslintrc file at the root of the project and configure ESLint.
{
"extends": "eslint-config-airbnb"
}
You can now check that the code for the current project conforms to preset rules.
The code .js index file is as follows.
var unusued = 'I have no purpose!';
function greet() {
var message = 'Hello, World!';
alert(message);
}
greet();
Checking this file with ESLint will report an error.
$ eslint index.js
index.js
1:1 error Unexpected var, use let or const instead no-var
1:5 error unusued is defined but never used no-unused-vars
4:5 error Expected indentation of 2 characters but found 4 indent
4:5 error Unexpected var, use let or const instead no-var
5:5 error Expected indentation of 2 characters but found 4 indent
✖ 5 problems (5 errors, 0 warnings)
The above code states that the original file has five errors,
let
two of which should not use the
var
command but let
const