文章是翻译,主要是很多 ES6 的用法技巧以及最佳实践~ 原文 https://github.com/DrkSephy/es6-cheatsheet ES6 手册这篇手册包含了 ES2015(ES6) 的使用小技巧、最佳实践以及可以给你每天的工作参考的代码片段。 内容列表
var 和 let/const 的比较
var snack = 'Meow Mix';
function getFood(food) {
if (food) {
var snack = 'Friskies';
return snack;
}
return snack;
}
getFood(false); // undefined 当我们用 let 代替 var 的时候,观察会发生什么: let snack = 'Meow Mix';
function getFood(food) {
if (food) {
let snack = 'Friskies';
return snack;
}
return snack;
}
getFood(false); // 'Meow Mix' 当我们重构使用 var 的老代码的时候应该注意上面的变化。盲目地使用 let 替换 var 可能会出现出乎意料的情况。
console.log(x); // ReferenceError: x is not defined
let x = 'hi';
用块级作用域代替 IIFES
IIFES: (function () {
var food = 'Meow Mix';
}());
console.log(food); // Reference Error 使用 ES6 的块级作用域: {
let food = 'Meow Mix';
}
console.log(food); // Reference Error 箭头函数我们经常需要给回调函数维护一个词法作用域的上下文 this。 function Person(name) {
this.name = name;
}
Person.prototype.prefixName = function (arr) {
return arr.map(function (character) {
return this.name character; // Cannot read property 'name' of undefined
});
}; 一个常用的解决办法是把 this 存在一个变量中: function Person(name) {
this.name = name;
}
Person.prototype.prefixName = function (arr) {
var that = this; // Store the context of this
return arr.map(function (character) {
return that.name character;
});
}; 我们也可以传递一个合适的 this 上下文: function Person(name) {
this.name = name;
}
Person.prototype.prefixName = function (arr) {
return arr.map(function (character) {
return this.name character;
}, this);
} 我们还可以绑定上下文: function Person(name) {
this.name = name;
}
Person.prototype.prefixName = function (arr) {
return arr.map(function (character) {
return this.name character;
}.bind(this));
}; 使用 箭头函数,this 将不会受到影响,并且我们可以重写上面的函数: function Person(name) {
this.name = name;
}
Person.prototype.prefixName = function (arr) {
return arr.map(character => this.name character);
};
在我们写一个函数的时候,箭头函数更加简洁并且可以很简单地返回一个值: var squares = arr.map(function (x) { return x * x }); // Function Expression const arr = [1, 2, 3, 4, 5];
const squares = arr.map(x => x * x); // Arrow Function for terser implementation
字符串在 ES6 中,标准库升级了很多,在这些变化中有许多新的对于字符串的函数,比如 .includes() 和 .repeat()。 .includes( )var string = 'food';
var substring = 'foo';
console.log(string.indexOf(substring) > -1); 之前我们使用 indexOf() 函数的返回值是否 >-1 来判断字符串是否包含某些字符串,现在我们更简单地使用 .includes() 来返回一个布尔值来判断: const string = 'food';
const substring = 'foo';
console.log(string.includes(substring)); // true .repeat( )function repeat(string, count) {
var strings = [];
while(strings.length < count) {
strings.push(string);
}
return strings.join('');
} 在 ES6 中,可以更简便地实现: // String.repeat(numberOfRepetitions)
'meow'.repeat(3); // 'meowmeowmeow' 模版字符串使用 模版字符串 我们就可以不用对某些特殊自负进行转义处理了: var text = 'This string contains \'double quotes\' which are escaped.'; let text = `This string contains 'double quotes' which don't need to be escaped anymore.`; 模版字符串 还支持插入,可以把变量值和字符串连接起来. var name = 'Tiger';
var age = 13;
console.log('My cat is named ' name ' and is ' age ' years old.'); 更简单: const name = 'Tiger';
const age = 13;
console.log(`My cat is named ${name} and is ${age} years old.`); 在 ES5 中,需要换行时,需要这样: var text = (
'cat\n'
'dog\n'
'nickelodeon'
); 或者这样: var text = [
'cat',
'dog',
'nickelodeon'
].join('\n'); 模版字符串 可以支持换行并且不需要额外的处理: let text = ( `cat
dog
nickelodeon`
); 模版字符串 还支持表达式: let today = new Date();
let text = `The time and date is ${today.toLocaleString()}`; 解构结构可以让我们用一个更简便的语法从一个数组或者对象(即使是深层的)中分离出来值,并存储他们。 结构数组var arr = [1, 2, 3, 4];
var a = arr[0];
var b = arr[1];
var c = arr[2];
var d = arr[3]; let [a, b, c, d] = [1, 2, 3, 4];
console.log(a); // 1
console.log(b); // 2 结构对象var luke = { occupation: 'jedi', father: 'anakin' };
var occupation = luke.occupation; // 'jedi'
var father = luke.father; // 'anakin' let luke = { occupation: 'jedi', father: 'anakin' };
let {occupation, father} = luke;
console.log(occupation); // 'jedi'
console.log(father); // 'anakin' 模块在 ES6 之前,我们使用 Browserify 这样的库来创建客户端的模块化,在 node.js 中使用 require。 使用 CommonJS 的出口module.exports = 1;
module.exports = { foo: 'bar' };
module.exports = ['foo', 'bar'];
module.exports = function bar () {}; 使用 ES6 的出口在 ES6 中我们可以暴漏多个值,使用 Exports: export let name = 'David';
export let age = 25; 或者暴露一个对象列表: function sumTwo(a, b) {
return a b;
}
function sumThree(a, b, c) {
return a b c;
}
export { sumTwo, sumThree }; 我们还可以暴露函数、对象和其他的值,通过简单地使用 export 这个关键字: export function sumTwo(a, b) {
return a b;
}
export function sumThree(a, b, c) {
return a b c;
} 最后,我们还可以绑定一个默认的输出: function sumTwo(a, b) {
return a b;
}
function sumThree(a, b, c) {
return a b c;
}
let api = {
sumTwo,
sumThree
};
export default api;
/* Which is the same as
* export { api as default };
*/
ES6 中的导入在 ES6 中同样提供了多样的导入方式,我们可以这么导入一个整个文件: import 'underscore';
和 Python 中类似,我们可以命名导入的值: import { sumTwo, sumThree } from 'math/addition'; 我们还可以重命名导入: import {
sumTwo as addTwoNumbers,
sumThree as sumThreeNumbers
} from 'math/addition'; 另外,我们可以导入所有的东西(整体加载): import * as util from 'math/addition'; 最后,我们可以从一个模块中导入一个值的列表: import * as additionUtil from 'math/addition';
const { sumTwo, sumThree } = additionUtil; 可以像这样导入默认绑定的输出: import api from 'math/addition';
// Same as: import { default as api } from 'math/addition'; 虽然最好保持出口的简单,但如果需要的话我们有时可以混合默认的进口和混合进口。当我们这样出口的时候: // foos.js
export { foo as default, foo1, foo2 }; 我们可以这样导入它们: import foo, { foo1, foo2 } from 'foos'; 当我们用 commonjs 的语法导入一个模块的出口时(比如 React),我们可以这样做: import React from 'react';
const { Component, PropTypes } = React; 还有更精简的写法: import React, { Component, PropTypes } from 'react';
参数在 ES5 中,在函数中我们需要各种操作去处理 默认参数、不定参数 和 重命名参数 等需求,在 ES6 中我们可以使用更简洁的语法完成这些需求: 默认参数function addTwoNumbers(x, y) {
x = x || 0;
y = y || 0;
return x y;
} ES6 中,函数的参数可以支持设置默认值: function addTwoNumbers(x=0, y=0) {
return x y;
} addTwoNumbers(2, 4); // 6
addTwoNumbers(2); // 2
addTwoNumbers(); // 0 rest 参数在 ES5 中,我们需要这么处理不定参数: function logArguments() {
for (var i=0; i < arguments.length; i ) {
console.log(arguments[i]);
}
} 使用 rest ,我们就可以处理不确定数目的参数: function logArguments(...args) {
for (let arg of args) {
console.log(arg);
}
} 命名参数在 ES5 中是使用配置对象的模式来处理命名参数,jQuery 中的使用: function initializeCanvas(options) {
var height = options.height || 600;
var width = options.width || 400;
var lineStroke = options.lineStroke || 'black';
} 我们可以利用解构的一个函数的形参实现相同的功能: function initializeCanvas(
{ height=600, width=400, lineStroke='black'}) {
// Use variables height, width, lineStroke here
} 如果我们想使整个值可选择,我们可以结构将一个空的对象: function initializeCanvas(
{ height=600, width=400, lineStroke='black'} = {}) {
// ...
} 展开操作在 ES5 中,我们可以 apply Math.max 方法来获得一个数组中的最大值: Math.max.apply(null, [-1, 100, 9001, -32]); // 9001 在 ES6 中,我们可以通过展开操作把一个数组的值作为参数传递给一个函数: Math.max(...[-1, 100, 9001, -32]); // 9001 我们可以更简洁地使用这个语法来合并数组: let cities = ['San Francisco', 'Los Angeles'];
let places = ['Miami', ...cities, 'Chicago']; // ['Miami', 'San Francisco', 'Los Angeles', 'Chicago'] 类 Classes在 ES6 之前,我们通过构造函数来创造一个类,并且通过原型来扩展属性: function Person(name, age, gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
Person.prototype.incrementAge = function () {
return this.age = 1;
}; 然后可以这样继承类: function Personal(name, age, gender, occupation, hobby) {
Person.call(this, name, age, gender);
this.occupation = occupation;
this.hobby = hobby;
}
Personal.prototype = Object.create(Person.prototype);
Personal.prototype.constructor = Personal;
Personal.prototype.incrementAge = function () {
Person.prototype.incrementAge.call(this);
this.age = 20;
console.log(this.age);
}; 在 ES6 中,提供了更多的语法糖,可以直接创造一个类: class Person {
constructor(name, age, gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
incrementAge() {
this.age = 1;
}
} 使用 extends 关键字来继承一个类: class Personal extends Person {
constructor(name, age, gender, occupation, hobby) {
super(name, age, gender);
this.occupation = occupation;
this.hobby = hobby;
}
incrementAge() {
super.incrementAge();
this.age = 20;
console.log(this.age);
}
}
SymbolsSymbols 在 ES6 之前就已经存在,但是我们现在可以直接使用一个开发的接口了。Symbols 是不可改变并且是第一无二的,可以在任意哈希中作一个key。Symbol() 调用 Symbol() 或者 Symbol(description) 可以创造一个第一无二的符号,但是在全局是看不到的。Symbol() 的一个使用情况是给一个类或者命名空间打上补丁,但是可以确定的是你不会去更新它。比如,你想给 React.Component 类添加一个 refreshComponent 方法,但是可以确定的是你不会在之后更新这个方法: const refreshComponent = Symbol();
React.Component.prototype[refreshComponent] = () => {
// do something
} Symbol.for(key)Symbol.for(key) 同样会创造一个独一无二并且不可改变的 Symbol,但是它可以全局看到,两个相同的调用 Symbol.for(key) 会返回同一个 Symbol 类: Symbol('foo') === Symbol('foo') // false
Symbol.for('foo') === Symbol('foo') // false
Symbol.for('foo') === Symbol.for('foo') // true 对于 Symbols 的普遍用法(尤其是Symbol.for(key))是为了协同性。它可以通过在一个第三方插件中已知的接口中对象中的参数中寻找用 Symbol 成员来实现,比如: function reader(obj) {
const specialRead = Symbol.for('specialRead');
if (obj[specialRead]) {
const reader = obj[specialRead]();
// do something with reader
} else {
throw new TypeError('object cannot be read');
}
} 在另一个库中: const specialRead = Symbol.for('specialRead');
class SomeReadableType {
[specialRead]() {
const reader = createSomeReaderFrom(this);
return reader;
}
} 原文:https://github.com/DrkSephy/es6-cheatsheet 译文:http:///post/es6-cheatsheet.html
|
|