1
0
mirror of https://github.com/ruanyf/es6tutorial.git synced 2025-05-25 19:22:21 +00:00
es6tutorial/docs/style.md
2015-03-04 18:51:25 +08:00

242 lines
4.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 编程风格
本章探讨如何将ES6的新语法运用到编码实践之中与传统的JavaScript语法结合在一起以及如何形成良好的编码风格。
## 块级作用域
**1let取代var**
ES6提出了两个新的声明变量的命令let和const。其中let完全可以取代var因为两者语义相同而且let没有副作用。
```javascript
"use strict";
if(true) {
let x = 'hello';
}
for (let i = 0; i < 10; i++) {
console.log(i);
}
```
上面代码如果用var替代let实际上就声明了一个全局变量这显然不是本意。变量应该只在其声明的代码块内有效var命令做不到这一点。
var命令存在变量提升效用let命令没有这个问题。
```javascript
"use strict";
if(true) {
console.log(x); // ReferenceError
let x = 'hello';
}
```
上面代码如果使用var替代letconsole.log那一行就不会报错而是会输出undefined因为变量声明提升到代码块的头部。这违反了变量先声明后使用的原则。
所以建议不再使用var命令而是使用let命令取代。
**2全局常量和线程安全**
在let和const之间建议优先使用const尤其是在全局环境不应该设置变量只应设置常量。这符合函数式编程思想有利于将来的分布式运算。
```javascript
// 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声明常量还有两个好处一是阅读代码的人立刻会意识到不应该修改这个值二是防止了无意间修改变量值所导致的错误。
所有的函数都应该设置为常量。
let表示的变量只应出现在单线程运行的代码中不能是多线程共享的这样有利于保证线程安全。
**3严格模式**
V8引擎只在严格模式之下支持let和const。结合前两点这实际上意味着将来所有的编程都是针对严格模式的。
## 字符串
静态字符串一律使用单引号或反引号,不使用双引号。动态字符串使用反引号。
```javascript
// 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';
```
## 对象
单行定义的对象,最后一个成员不以逗号结尾。多行定义的对象,最后一个成员以逗号结尾。
```javascript
// 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,
};
```
对象尽量静态化一旦定义就不得随意添加新的属性。如果添加属性不可避免要使用Object.assign方法。
```javascript
// bad
const a = {};
a.x = 3;
// if reshape unavoidable
const a = {};
Object.assign(a, { x: 3 });
// good
const a = { x: null };
a.x = 3;
```
## 函数
使用匿名函数的场合,一律改为使用箭头函数。
```javascript
// bad
arr.reduce(function(x, y) { return x + y; }, 0);
// good
arr.reduce((x, y) => x + y, 0);
```
箭头函数取代Function.prototype.bind不应再用 self / _this / that 绑定 this。
```javascript
// 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);
```
所有配置项都应该集中在一个对象,放在最后一个参数,布尔值不可以直接作为参数。
```bash
// bad
function divide(a, b, option = false ) {
}
// good
function divide(a, b, { option = false } = {}) {
}
```
## Map结构
注意区分Object和Map只有模拟实体对象时才使用Object。如果只是需要key:value的数据结构使用Map。因为Map有内建的遍历机制。
```javascript
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]);
}
```
## 模块
使用import取代require。
```javascript
// bad
const moduleA = require('moduleA');
const func1 = moduleA.func1;
const func2 = moduleA.func2;
// good
import { func1, func2 } from 'moduleA';
```
使用export取代module.exports。
```javascript
// 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
```