1 Variable Declarations
let 的作用域在所声明的块中
// modern JavaScript
let variable = 5;
{
console.log('inside', variable); // error
let variable = 10;
}
console.log('outside', variable); // 5
variable = variable*2;
console.log('changed', variable); // 10
const 修饰的常量不允许更改,否则会报错
// modern JavaScript
const variable = 5;
variable = variable*2; // error
console.log('changed', variable); // doesn't get here
但const 修饰的array,object 需要注意,引用常量,值可以变
// modern JavaScript
const variable = [5];
console.log('const array', variable); // [5]
variable[0] = variable[0]*2;
console.log('changed const array', variable); // [10]
2 String Templates
var name = 'Oscar',
pet = 'cat',
speak = 'meow';
var s = `${name} has a ${pet} who says "${speak}".`;
console.log(s); // Oscar has a cat who says "meow"
// any JS fits inside {}
var s = `${name} has a ${pet+'dog'} who says "${speak}".`;
console.log(s); // Oscar has a catdog who says "meow"
3 Destructuring
翻译过来是“解构”,就你只描绘object的结构,ES6会填充里面的内容
Array数组解构:
// in ES6 array destructuring is awesome
let arr = [1,2,3,4];
let [a, b, c] = arr;
console.log(arr, a, b, c); // [1,2,3,4], 1, 2, 3
Object解构:
// in ES6 object destructuring is awesome
let obj = {a: 1, b: 2, c: 3};
let { a, b, c } = obj;
console.log(obj, a, b, c); // {"a":1,"b":2,"c":3}, 1, 2, 3
利用spread operator 解构,作为数组或对象的元素,事半功倍
// you can use the spread operator too
let arr = [1,2,3,4,5];
let [head, ...tail] = arr;
console.log(head, tail); // 1, [2,3,4,5]
let obj = {a: 1, b: 2, c: 3};
let {a, ...rest} = obj;
console.log(a, rest); // 1, {"b":2, "c":3}
4 Arrow Functions
要特别注意this,始终指向定义函数的对象
ES5的写法:
function ManyCounter (values) {
this.values = values;
}
ManyCounter.prototype.incAll = function () {
this.values.map(function (n, i) {
this.values[i] += 1;
}.bind(this)) // must bind function to this
}
var counter = new ManyCounter([1, 2, 3, 4]);
counter.incAll();
console.log(counter.values); // [2,3,4,5]
ES6的写法:
function ManyCounter (values) {
this.values = values;
}
ManyCounter.prototype.incAll = function () {
this.values.map((n, i) => this.values[i] += 1);
}
var counter = new ManyCounter([1, 2, 3, 4]);
counter.incAll();
console.log(counter.values); // [2,3,4,5]
5 Function Parameters
形参默认值一行代码搞定
// default params are easy in ES6
function sum (a = 0, b = 0) {
return a+b;
}
console.log(sum(2)); // 2
命名参数的默认值也一样
// named params are great
function rectArea ({ width = 5, height = 5 } = {}) {
return width*height;
}
console.log(rectArea()); // 25
console.log(rectArea({})); // 25
console.log(rectArea({width: 3, height: 30})); // 90
spread operator 有的称作 rest operator,方便类数组的处理
// rest params are nice
function sum (...vals) {
// vals looks like [1,2,3,4]
return vals.reduce((sum, n) => sum+n, 0);
}
console.log(sum(1, 2, 3, 4)); // 10
6 Classes
注意class 关键字是小写!
class Cat {
constructor (name, color) {
this.name = name;
this.color = color;
}
present () {
return `${this.name} is ${this.color}`;
}
}
var cat = new Cat('Mici', 'dark brown');
console.log(cat.present()); // Mici is dark brown
类的继承,使用super,extends
// ES6 syntax sugar improves classes
class Cat {
constructor (name, color) {
this.name = name;
this.color = color;
}
present () {
return `${this.name} is ${this.color}`;
}
}
class Tabby extends Cat {
constructor (name) {
super(name, ['Orange', 'White']);
}
present () {
return `${super.present()} and she's cool`;
}
}
let cat = new Tabby('Friskies Cat', 'Friskies Cat');
console.log(cat.present()); // Friskies Cat is Orange,White and she's cool
7 Getters/Setters
操作属性,读和写都可以加入额外的操作,但需要注意属性前要加下划线_
// ES6 getters/setters are great
class Cat {
constructor (name, gender) {
this._name = name;
this.gender = gender;
}
// name is like a property, but calculatable
get name () {
if (this.gender == 'female') {
return `Ms. ${this._name}`;
}else{
return `Mr. ${this._name}`;
}
}
set name (newName) {
if (newName) {
this._name = newName;
}else{
console.log("I need a name");
}
}
}
let cat = new Cat('Mici', 'female');
console.log(cat.name); // Ms. Mici
cat.name = null; // I need a name
cat.name = 'John'
cat.gender = 'male';
console.log(cat.name); // Mr. John
8 Modules
ES6中用import,export 替换了require和module.exports
ES5中
// with some tooling, ES5 can do require()
// ./MyCode.js
var AwesomeLibrary = require('AwesomeLibrary');
AwesomeLibrary.MainThing.do_something()
AwesomeLibrary.Helper.something_else();
// AwesomeLibrary.js
var AwesomeLibraryClass = ;// ...
var SmallThingy = ;// ...
module.exports = {
MainThing: AwesomeLibraryClass,
Helper: SmallThingy
}
ES6中
// ES6 comes with modules
// ./MyCode.js
import AwesomeLibrary from 'AwesomeLibrary';
import { Helper as AwesomeHelper } from 'AwesomeLibrary';
AwesomeLibrary.do_something()
AwesomeHelper.something_else();
// AwesomeLibrary.js
class AwesomeLibraryClass () {};// ...
const SmallThingy = {};// ...
export default AwesomeLibraryClass;
export { SmallThingy as Helper };
9 Data Structure
加入了hasmaps
// ES6 implements real hashes
let key2 = 'key2';
let hash = new Map([
['key1', 'val1'],
[key2, 'val2'],
[true, 'yes']
])
//hash.key3 = 'val3';
console.log(hash.get(true)); // yes
console.log(hash.has('key3')); // false
// key1, val1
// key2, val2
// true, yes
for (let [key, val] of hash.entries()) {
console.log(key, val);
}
sets
// ES6 sets are cool too
let set = new Set([1, 2, 1, 1, 3, 4, 5, 4, 3]);
console.log(set.size); // 5
console.log(set.has(5)); // true
set.forEach(n => console.log(n)); // 1, 2, 3, 4, 5