在ECMAScript 2015(ES6)语言标准中,扩展了一些新的语法特性,这些语法特性使JavaScript语言更加规范化,让语言使用也更加便捷。如:新增的块级变量及常量定义方式,弥补了原有一些语言缺陷;解构赋值可以更方便的从数组或对象中提取值。
1. 变量常量定义
1.1 let与块级变量声名
ES6 发布之前,JavaScript只能使用var来定义变量。但通过var定义的变量是全局的或是函数级的,在语句块内定义的变量,可以全局访问:
for (var i = 0; i < 5; i++) {
var myVar = 'niefengjun.cn';
}
console.log(i); // 5
console.log(myVar); // 'niefengjun.cn'
let只能在严格模式下使用,其定义变量的方式与var类似,可以定义一个或多个变量,可以对定义的变量赋值或不赋值。但其与var定义的变量有以下两点区别:
let定义变量是块级的,而var定义的变量是全局的let不能定义名称重复的变量,重复定义会引发TypeError错识
如,使用let定义块级变量:
'use strict'
for (let i = 0; i < 5; i++) {
let myVar = 'niefengjun.cn';
}
console.log(i); // ReferenceError: i is not defined
console.log(myVar); // ReferenceError: myVar is not defined
1.2 const与常量声名
ES6 中还新增了定义常量的方式,定义一个常量使用const关键字。常量定义有以下特点:
- 定义常量的同时必须对其初始化,否则会抛出
SyntaxError异常 - 常量定义后,不能对其重新赋值,否则会抛出
TypeError异常 - 常量名不能与其它常量、变量名称重复,否则会抛出
SyntaxError异常
如,常量的使用:
// 常量名可以是大写或小写形式,但在习惯上使用大写定义 const MY_FAV = 7; // 对常量重新赋值时会发生TypeError MY_FAV = 20; //TypeError // 定义重复的常量名或变量名时会发生SyntaxError错误 const MY_FAV2 = 20; //SyntaxError var MY_FAV2 = 20; //SyntaxError //常量声明时,必须同时对其初化,否则会发生SyntaxError错误 const FOO; // SyntaxError
2. 解构赋值
解构赋值(Destructuring assignment)是ES6 新增的一种JavaScript表达语法。解构赋值使得从数组或者对象中提取数据,并赋值给不同的变量成为可能。
解构赋值是从对象字面量和数组字面量中提取数据的便捷方式,解构赋值的有一个特别有用的功能是:可以用一个表达式读取整个结构。
var [a, b] = [1, 2];
console.log(a); // 1
console.log(b); // 2
var [a, b, ...rest] = [1, 2, 3, 4, 5]
console.log(a); // 1
console.log(b); // 2
console.log(rest); //[3,4,5]
var {a, b} = {a:1, b:2};
console.log(a); // 1
console.log(b); // 2
{a, b, ...rest} = {a:1, b:2, c:3, d:4}
//ES7
2.1 解构数组
以下是从数组字面量中解构赋值的一些使用示例:
简单示例
var foo = ["one", "two", "three"]; // 非解构赋值 var one = foo[0]; var two = foo[1]; var three = foo[2]; // 解构赋值 var [one, two, three] = foo;
变量交换
解构赋值可以让我们在不定义监时变量的情况下,交换两个变量的值:
var a = 1; var b = 3; [a, b] = [b, a];
返回多个值
使用解构赋值,使我们可以用类似数组的方式,返回多个变量:
function f() {
return [1, 2];
}
// 解构式返回
var a, b;
[a, b] = f();
// 数组式返回
var arr = f();
选择性提取
通过解构赋值返回值时,可以忽略部分不需要的值:
function f() {
return [1, 2, 3];
}
var [a, , b] = f();
console.log("A是 " + a + ",B是 " + b); // A是 1,B是3
或者使用正则表达式提取所需要的部分:
var url = "http://niefengjun.cn/nodejs/core"; var parsedURL = /^(\w+)\:\/\/([^\/]+)\/(.*)$/.exec(url); var [, protocol, fullhost, fullpath] = parsedURL; console.log(fullhost); // 'niefengjun.cn'
2.2 解构对象
解构对象与解构数组使用类似,二者也可以混合使用。以下是从对象字面量中解构赋值的一些使用示例:
简单示例
var o = {p: 42, q: true};
var {p, q} = o;
console.log(p); // 42
console.log(q); // true
// 用新变量名赋值
var {p: foo, q: bar} = o;
console.log(foo); // 42
console.log(bar); // true
对象属性与解构
在计算对象属性名时,可以使用解构:
let key = "z";
let { [key]: foo } = { z: "bar" };
console.log(foo); // "bar"
参数默认值
ES6 通过解构对象,实现了函数参数默认值:
function post({url:'niefengjun.cn', port:80, data:{content:''}}) {
console.log(url, port, data);
// 一些操作
}
post({
data:{
title:'文章的标题',
content:'文章的内容'
}
};)
模块加载
ES6 中定义了模块机制,在使用import关键字导入模块时,同样支持使用解构。
如,定义my-module模块:
// "my-module.js" 模块
export function cube(x) {
return x * x * x;
}
const foo = Math.PI + Math.SQRT2;
export { foo };
导入模块,并使用解构赋值:
import { cube, foo } from 'my-module';
console.log(cube(3)); // 27
console.log(foo); // 4.555806215962888
for…of迭代与解构
解构同样能在for…of迭代中使用:
var sites = [
{
name: "IT笔录",
introduce: {
domain: "niefengjun.cn",
title: "IT笔录"
}
},
{
name: "老聂的小站",
introduce: {
domain: "niefengjun.cn",
title: "聂峰军,聂峰军个人博客"
}
},
{
name: "一介布衣",
introduce: {
domain: "yijiebuyi.com",
title: "一介布衣,专注 javascript 全栈开发"
}
}
];
for (var {name: n, introduce: { title: t, domain: url } } of sites) {
console.log("name: " + n + ", title: " + t + ", url: " + url);
}
3. for…of循环
在ES5中我们可以全用for…in结构,来遍历一个数组结构。通过for…in循环可以获取数组索引,而ES6新增的for…of可以直接遍历获取数组值:
let iterable = [10, 20, 30];
for (let idx in iterable) {
console.log(idx); // 依次输出:0, 1, 2
}
for (let value of iterable) {
console.log(value); // 依次输出:10, 20, 30
}
4. 展开(...)语法
Spread语法在用于表达的某处展开,展开语法使用...符号表示。要展开的内容可能是多个函数参数(函数调用中)、多个元素(数组字面量)或多个变量(解构赋值中)。
语法结构为:
// 函数调用 myFunction(...iterableObj); // 数组字面量 [...iterableObj, 4, 5, 6]
在函数调用中使用
在 ES6 之前,我们会使用Function.prototype.apply方法来将一个数组展开成多个参数:
function myFunction(x, y, z) { }
var args = [0, 1, 2];
myFunction.apply(null, args);
通过 ES6 中的...运算符,我们可以这样写:
function myFunction(x, y, z) { }
var args = [0, 1, 2];
myFunction(...args);
也可以同时展开多个数组参数:
function myFunction(v, w, x, y, z) { }
var args = [0, 1];
myFunction(-1, ...args, 2, ...[3]);
在数组字面量中使用
...运算符让数组操作更加方便,我们可以很简单的通过一个已存在的数组构建一个新数组:
var parts = ['shoulders', 'knees']; var lyrics = ['head', ...parts, 'and', 'toes']; // ["head", "shoulders", "knees", "and", "toes"]
在解构赋值中使用
在解构赋值时,同样可以使用...运算符:
var a, b, rest; [a, b, ...rest] = [1, 2, 3, 4, 5]; console.log(a); // 1 console.log(b); // 2 console.log(rest); // [3, 4, 5]
