Slides in ES6 overview workshop
Intro
What
ECMAScript 6(以下简称ES6)是JavaScript语言的下一代标准
Goal
ES6的目标,是使得JavaScript语言可以用来编写大型的复杂的应用程序,成为企业级开发语言。 新的语言特性,代码更优雅,程序更健壮,减少不必要的重复,减少不必要的第三方依赖。
Agenda
- template strings
- const
- let
- block-level declaration
- Destructuring Assignment
- arrow functions
- default function params
- class
- module
Requirements
Babel https://babeljs.io/docs/usage/cli/
$ npm install --global babel
Talk is cheap, show me the code.
template strings
var first = "Song"
var last = "Yang";
var name = `I'm ${first} ${last}!`;
性能对比 http://heeroluo.net/article/detail/54
它可以当作普通字符串使用,也可以用来定义多行字符串,或者在字符串中嵌入变量。
const
const PI = 3.14
Object.defineProperty(typeof global === "object" ? global : window, "PI", {
value: 3.14,
enumerable: true,
writable: false,
configurable: false
})
let
声明变量,变量只在let命令所在代码块内有效。
{
var a = 1;
let b = 10;
}
a //1
b // ReferenceError: b is not defined.
let不允许在相同作用域内,重复声明同一个变量。
// error
{
let a = 10;
let a = 1;
}
block-level declaration
- let, const 块级作用域
- var 函数作用域
function fn() {
for(var i=0,len=5;i<len;i++) {
//body
}
console.log(i,len);=> 5,5
}
ES5的JavaScript的不支持块级作用域,变量仅仅被限制到函数作用域内。
Pros
// IIFE写法
(function () {
var tmp = ...;
...
}());
// 块级作用域写法
{
let tmp = ...;
...
}
function scope
function f() { console.log('I am outside!'); }
(function () {
if(false) {
// What should happen with this redeclaration?
function f() { console.log('I am inside!'); }
}
f();
}());
Destructuring Assignment
ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。
Array destructuring
var a = 1;
var b = 2;
var c = 3;
var [a, b, c] = [1, 2, 3];
[a, b] = [b, a];
模式匹配(嵌套数组)
var [foo, [[bar], baz]] = [1, [[2], 3]];
foo // 1
bar // 2
baz // 3
var [,,third] = ["foo", "bar", "baz"];
third // "baz"
var [head, ...tail] = [1, 2, 3, 4];
head // 1
tail // [2, 3, 4]
解构失败
var [foo] = [];
var [foo] = 1;
var [foo] = 'Hello';
var [foo] = false;
var [foo] = NaN;
var [bar, foo] = [1];
foo // undefined
- 如果对undefined或null进行解构,会报错。
// 报错
var [foo] = undefined;
var [foo] = null;
- 解构赋值允许指定默认值。
[x, y='b'] = ['a'] // x=3, y='b'
- 解构赋值不仅适用于var命令,也适用于let和const命令。
var [v1, v2, ..., vN ] = array;
let [v1, v2, ..., vN ] = array;
const [v1, v2, ..., vN ] = array;
Object destructuring
var { foo, bar } = { foo: "aaa", bar: "bbb" };
foo // "aaa"
bar // "bbb"
如果变量名与属性名不一致,必须写成下面这样。
var { foo: baz } = { foo: "aaa", bar: "bbb" };
baz // "aaa"
var o = {
p: [
"Hello",
{ y: "World" }
]
};
var { p: [x, { y }] } = o;
x // "Hello"
y // "World"
- 对象的解构也可以指定默认值。
- 如果要将一个已经声明的变量用于解构赋值
// 错误的写法
var x;
{x} = {x:1};
// SyntaxError: syntax error
({x} = {x:1});
JavaScript引擎会将{x}
理解成一个代码块,从而发生语法错误。
NOTE 数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。
Pros
- 交换变量的值
- 从函数返回多个值
- 遍历Map结构
配合变量的解构赋值,获取键名和键值
for (let [key, value] of map) {
console.log(key + " is " + value);
} - 输入模块的指定方法
const { SourceMapConsumer, SourceNode } = require("source-map");
Arrow Function
- 语法糖:function的简写,或者是使用胖箭头 () => 的Lamda表达式。
- 不仅仅是语法糖:自动绑定外部作用域的"this".
const items = [1, 2, 3, 4];
var double = (x) => x * 2;
var byTwo = items.map(double);
// => [2, 4, 6, 8]
var foot = {
kickNormal: function () {
this.yelp = "Ouch!";
setImmediate(function () {
console.log(this.yelp);
}.bind(this));
},
kick: function () {
this.yelp = "Ouch!";
setImmediate(() => console.log(this.yelp));
}
};
default function params
在ES6默认值特性出现前,手动处理默认值有几种方式:
function log(message, level) {
level = level || 'warning';
console.log(level, ': ', message);
}
log('low memory'); // warning: low memory
log('out of memory', 'error'); // error: out of memory
为了处理参数未传递的情况,我们常看到typeof检测:
if (typeof level == 'undefined') {
level = 'warning';
}