Many companies and organizations have disclosed their style specifications. For details, please refer to jscs.info. The following content mainly refers to Airbnb's JavaScript style specifications. Of course, there are also programming suggestions from Google, etc.Programming Style
This chapter discusses how to use the new syntax of ES6, combined with the traditional JavaScript syntax, to write reasonable, easy-to-read and maintain code.
(1)let replaces var
ES6 proposes two new declarations Variable commands: let and const. Among them, let can completely replace var, because the semantics of the two are the same, and let has no side effects.
'use strict'; if (true) { let x = 'hello'; } for (let i = 0; i < 10; i++) { console.log(i); }
Note: If var is used instead of let in the above code, two global variables are actually declared, which is obviously not the intention. Variables should only be valid within the code block in which they are declared. The var command cannot do this.
The var command has variable promotion effect, but the let command does not have this problem:
'use strict'; if(true) { console.log(x); // ReferenceError let x = 'hello'; }
Note: If the above code uses var instead of let, the console.log line will not report an error, but will output undefined because the variable declaration is hoisted to the head of the code block. This violates the principle of variables being declared first and used later.
(2) Global constants and thread safety
const is better than let for several reasons. One is that const can remind people who read the program that this variable should not change; the other is that const is more in line with the idea of functional programming. The operation does not change the value, but only creates a new value, and this is also conducive to future distributed operations; the last reason The JavaScript compiler will optimize const, so using const more will help improve the running efficiency of the program. In other words, the essential difference between let and const is actually the different internal processing of the compiler.
// 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];
Note: There are two benefits of declaring a const constant. First, people reading the code will immediately realize that the value should not be modified. Second, it prevents errors caused by inadvertently modifying the variable value. JavaScript may have multi-threaded implementations (such as Intel's River Trail projects). In this case, the variables represented by let should only appear in code running in a single thread and cannot be shared by multiple threads. This will help ensure Thread safe.
Static strings always use single quotes or backticks, and do not use double quotes. Dynamic strings use backticks.
// bad const a = "foobar"; const b = 'foo' + a + 'bar'; // acceptable const c = `foobar`; // good const a = 'foobar'; const b = `foo${a}bar`; const c = 'foobar';
When using array members to assign values to variables, destructuring assignment is preferred.
const arr = [1, 2, 3, 4]; // bad const first = arr[0]; const second = arr[1]; // good const [first, second] = arr;
If the parameter of the function is a member of the object, destructuring assignment is preferred.
// 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 multiple values, the destructuring assignment of the object is preferred instead of the destructuring assignment of the array. This makes it easier to add return values later and change the order of return values.
// bad function processInput(input) { return [left, right, top, bottom]; } // good function processInput(input) { return { left, right, top, bottom }; } const { left, right } = processInput(input);
Object defined in a single line, the last member does not end with a comma. For objects defined on multiple lines, the last member ends with a comma.
// good const a = { k1: v1, k2: v2 }; const b = { k1: v1, k2: v2, };
The object should be as static as possible. Once defined, new attributes cannot be added at will. If adding attributes is unavoidable, use the Object.assign method.
// if reshape unavoidable const a = {}; Object.assign(a, { x: 3 }); // good const a = { x: null }; a.x = 3;
If the object's attribute name is dynamic, you can use attribute expressions to define it when creating the object.
// good const obj = { id: 5, name: 'San Francisco', [getKey('enabled')]: true, };
Use the spread operator (…) to copy an 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 an array-like object into an array.
const foo = document.querySelectorAll('.foo'); const nodes = Array.from(foo);
The immediate execution function can be written in the form of an arrow function.
(() => { console.log('Welcome to the Internet.'); })();
In those situations where function expressions need to be used, try to use arrow functions instead. Because this is more concise and binds 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 replaces Function.prototype.bind and should no longer use self/_this/that to bind this.
// 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);
For simple, single-line, and non-reusable functions, it is recommended to use arrow functions. If the function body is complex and has a large number of lines, the traditional function writing method should be used.
All configuration items should be concentrated in one object and placed as the last parameter. Boolean values cannot be used directly as parameters.
// bad function pide(a, b, option = false ) { } // good function pide(a, b, { option = false } = {}) { }
Don’t use arguments variables in the function body, use rest operator (…) instead. Because the rest operator explicitly states that you want to get the parameters, 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 default value syntax to set default values for function parameters.
// bad function handleThings(opts) { opts = opts || {}; } // good function handleThings(opts = {}) { // ... }
Use Object only when simulating entity objects in the real world. If you only need the 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]); }
Module syntax is the standard way of writing JavaScript modules, stick to this way of writing. Use import instead of require. The usual way of writing is as follows:
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'; const Breadcrumbs = React.createClass({ render() { return <nav />; } }); export default Breadcrumbs
If the module has only one output value, use export default. If the module has multiple output values, do not use export default. , do not use export default and ordinary export at the same time.
Do not use wildcard characters in module input. Because this ensures that there is a default output (export default) in your module.
import myObject from './importModule';
If the module outputs a function by default, the first letter of the function name should be lowercase. This is also the coding style of camel case naming.
function makeStyleGuide() {} export default makeStyleGuide;
如果模块默认输出一个对象,对象名的首字母应该大写。
const StyleGuide = { es6: { } }; export default StyleGuide;
ESLint是一个语法规则和代码风格的检查工具,可以用来保证写出语法正确、风格统一的代码。和lint的使用差不多
首先,安装ESLint。
npm i -g eslint
然后,安装Airbnb语法规则。
npm i -g eslint-config-airbnb
最后,在项目的根目录下新建一个.eslintrc文件,配置ESLint。
{ "extends": "eslint-config-airbnb" }
比如:
var unusued = 'I have no purpose!'; function greet() { var message = 'Hello, World!'; 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)!