ES6语法介绍
§1 块级作用域(Block-Scoped Declarations)
说到块级作用域,最普遍的方式是IIFE(immediately invoked function expression)
,如:
var a = 2;
(function IIFE(){
var a = 3;
console.log(a); // 3
})()
console.log(a); // 2
let声明( let declaration)
在ES6
中,我们可以用一对{..}
来创建作用域,在{..}
中用let
声明变量的方式来创建块作用域,如:
var a = 2;
{
let a = 3;
console.log(a); // 3
}
console.log(a); // 2
** let声明切记要在域的顶部,避免过早获取而产生意外的错误。 **
常量声明( const declaration)
所谓常量,是指值初始化之后read-only
的变量,常量声明必须explicit initialization
。
{
const a = 2;
console.log(a); // 2
a = 3; // TypeError
}
常量并不局限于值 value
本身,换句话说,value
不是被冻结的,如果value
比较复杂,如object
或者array
,value
的内容仍然是可以被修改的。
const arr = [1,2,3];
arr.push(4);
console.log(arr); // [1,2,3,4]
arr = 42; // TypeError!
§2 Spread/Rest 操作符(... operator)
ES6
中介绍了一个新的...
操作符,是指Spread
还是Rest
,取决于我们怎么用它。
Spread
function foo(x, y, z){
console.log(x, y, z);
}
foo(...[1,2,3]); // 1, 2, 3
var a = [2,3,4];
var b = [1, ...a, 5];
console.log(b); // 1, 2, 3, 4, 5
Rest
function foo(x, y, ...z){
console.log(x, y, z);
}
foo(...[1,2,3,4,5,6]); // 1, 2, [3,4,5,6]
function bar(...args){
console.log(args);
}
bar(1,2,3,4,5); // [1,2,3,4,5]
§3 默认参数值(Default Parameter Values)
为一个function
参数设置默认值的最普遍的方式是:
function foo(x, y){
x = x || 11;
y + y || 31;
console.log(x + y);
}
foo(); // 42
foo(5, 6); // 11
foo(5); // 36
foo(null, 6); // 17
foo(undefined, 6); // 17
foo(0, 42); // 53 <-- Oops, not 42
这种方式存在一点危险,就是当你传入的值为0
时,如foo(0, 42)
,获得的不是我们所期待的值42
,而是53
在ES6
中,可以用以下方式设置默认参数值
function foo(x = 11, y = 31){
console.log(x + y);
}
foo(); // 42
foo(5, 6); // 11
foo(5); // 36
foo(null, 6); // 6 'null' coerces to '0'
foo(undefined, 6); // 17 'undefined' is missing
foo(0, 42); // 42
** JavaScript的设计原则:'Undefined' means missing **
§4 解构赋值(Destructuring)
destructuring
是ES6
新的语法特征,如果你把它理解成结构化的赋值structured assignment
就没有那么多困惑了。
function foo(){
return [1,2,3];
}
var tmp = foo(),
a = tmp[0], b = tmp[1]; c = tmp[2];
console.log(a, b, c); // 1, 2, 3
function bar(){
return {
x: 4,
y: 5,
z: 6
};
}
var tmp1 = bar(),
x= tmp1.x, y= tmp1.y; z= tmp1.z;
console.log(x, y, z); // 4, 5, 6
通过数组的索引或者对象的属性来赋值被认为是structured assignment
。
ES6
为array destructuring
和objectdestructuring
提供了专用的语法,消除了之前代码片段中tmp
这个中间变量的使用,使代码更简洁清晰。
var [a, b, c] = foo();
console.log(a, b, c); // 1, 2, 3
var {x: x, y: y, z: z} = bar();
console.log(x, y, z); // 4, 5, 6
destructuring
只是一般的赋值运算,并不是声明
var a, b, c, x, y, z;
[a, b, c] = foo()
( {x, y, z} = bar() )
console.log(a, b, c); // 1, 2, 3
console.log(x, y, z); // 4, 5, 6
** 如果是 object destructuring
,在解构赋值的时没有用到 let/var/const
标识符,要用一对 ()
将赋值表达式包起来,因为JavaScript通常会将 {}
起始的语句解析为一个块,而不是作为对象 **
§5 对象字面量扩展(Object Literal Extensions)
Concise Properties
你已经很熟悉下面这种声明对象字面量的方式:
var x = 2, y = 3;
var o = {
x: x,
y: y
}
但是对于x: x
这种写法很冗余,在ES6
中,如果定义的属性名称和语法标识符的名称相同,可以简写如下:
var x = 2, y = 3;
var o = {
x,
y
}
Concise Methods
The old way:
var o = {
x: function(){
// ..
},
y: function(){
// ..
}
}
And as of ES6:
var o = {
x() {
// ..
} ,
y() {
// ..
}
}
§6 模板文本(Template Literals)
Old Pre-ES6 way:
var name = "Kyle";
var greeting = "Hello " + name + "!";
console.log(greeting); // "Hello Kyle!"
The new ES6 way:
var name = `Kyle`;
var greeting = `Hello ${name}!`;
console.log(greeting); // "Hello Kyle!"
通过一对反引号来定义字符串表达式,通过${..}
来计算表达式,任何有效的表达式都是被允许放在${..}
里面。
function upper(s){
return s.toUpperCase();
}
var who = "reader";
var text =`A very ${upper( "warm" )} welcometo all of you ${upper( `${who}s` )}!`;
console.log(text); // A very WARM welcome to all of you READERS
使用反引号还能解决多行字符串的问题。
var text = `You are very lovely You are very lovely
You are very smart you are very smart
You are cute you are cute you are cute`;
console.log(text);
// You are very lovely You are very lovely
// You are very smart you are very smart
// You are cute you are cute you are cute
§7 Arrow Function
Arrow Function
是由参数列表、=>
标记符和方法体组成: (..) => {..}
function foo(x, y){
return x + y;
}
//arrow function
var foo = (x, y) => x + y ;
如果方法体中只有一个表达式或者没有表达式的情况下,可以省略{ }
,如果该方法只有一个参数,可以省略 ( )
。
var f1 = () => 12;
var f2 = x => x * 2;
var f3 = (x, y) => {
var z = x * 2 + y;
y++;
x *= 3;
return (x + y + z) / 2;
}
f1(); // 12
f2(2); // 4
f3(1, 2); // 5
var a = [1,2,3,4,5];
a = a.map(v => v * 2);
console.log(a); // [2,4,6,8,10]
§8 for .. in 和 for .. of Loops
var a = ["a", "b", "c", "d", "e"];
for(var idx in a){
console.log(idx);
}
// 0 1 2 3 4
for(var value of a){
console.log(value);
}
// "a" "b" "c" "d" "e"
** for .. in 是对 索引/键 的循环遍历 **
** for .. of 是对 值 的循环遍历 **