前言
ECMAScript 6(以下簡(jiǎn)稱ES6)是JavaScript語(yǔ)言的下一代標(biāo)準(zhǔn)。因?yàn)楫?dāng)前版本的ES6是在2015年發(fā)布的罪治,所以又稱ECMAScript 2015。
Babel轉(zhuǎn)碼器
Babel
Babel是一個(gè)廣泛使用的ES6轉(zhuǎn)碼器册着,可以將ES6代碼轉(zhuǎn)為ES5代碼判莉,從而在現(xiàn)有環(huán)境執(zhí)行。大家可以選擇自己習(xí)慣的工具來(lái)使用使用Babel托呕,具體過(guò)程可直接在Babel官網(wǎng)查看:
let和const命令
基本用法
用來(lái)聲明變量含蓉,但是所有聲明的變量只在let命令所在的代碼塊中有效;
var a = [];
for (let i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a[6](); // 6
變量i是let聲明的,當(dāng)前的i只在本輪循環(huán)有效项郊,所以每一次循環(huán)的i其實(shí)都是一個(gè)新的變量馅扣,所以最后輸出的是6。
不存在變量提升
let命令改變了語(yǔ)法行為着降,它所聲明的變量一定要在聲明后使用差油,否則報(bào)錯(cuò)。
// let 的情況
console.log(error); // 報(bào)錯(cuò)ReferenceError
let error = 2;
塊級(jí)作用域
function fun() {
let n = 5;
if (true) {
let n = 10;
}
console.log(n); // 5
}
上面的函數(shù)有兩個(gè)代碼塊任洞,都聲明了變量n蓄喇,運(yùn)行后輸出 5。這表示外層代碼塊不受內(nèi)層代碼塊的影響交掏。
不能重復(fù)聲明變量
let不允許在相同作用域內(nèi)妆偏,重復(fù)聲明同一個(gè)變量。
function func() {
let a = 10;
let a = 1;
console.log(a); // 報(bào)錯(cuò)
}
function func(a) {
let a; // 報(bào)錯(cuò)
}
function func(a) {
{
let a; // 不報(bào)錯(cuò)
}
}
const
const也用來(lái)聲明變量盅弛,但是聲明的是常量钱骂。一旦聲明,常量的值就不能改變挪鹏。
const命令的常量 也是不提升见秽,同樣存在暫時(shí)性死區(qū),只在聲明所在的塊級(jí)作用域內(nèi)有效.
const聲明的常量狰住,也與let一樣不可重復(fù)聲明张吉。
var message = "Hello!";
let age = 25;
const message = "Goodbye!";// 報(bào)錯(cuò)
const age = 30;// 報(bào)錯(cuò)
和let一樣不可重復(fù)聲明
if (true) {
const fun = 5;
}
fun // Uncaught ReferenceError: fun is not defined
塊級(jí)作用域
變量的解構(gòu)賦值
ES6 允許按照一定模式,從數(shù)組和對(duì)象中提取值催植,對(duì)變量進(jìn)行賦值,這被稱為解構(gòu)
let { foo, bar } = { foo: "aaa", bar: "bbb" };
foo // "aaa"
bar // "bbb"
----------------------
const [a, b, c, d, e] = 'hello';
a // "h"
b // "e"
c // "l"
d // "l"
e // "o"
Symbol
ES6 引入了一種新的原始數(shù)據(jù)類型Symbol勺择,表示獨(dú)一無(wú)二的值创南。
它是 JavaScript 語(yǔ)言的第七種數(shù)據(jù)類型,前六種是:undefined省核、null稿辙、布爾值(Boolean)、字符串(String)气忠、數(shù)值(Number)邻储、對(duì)象(Object)赋咽。
注意,Symbol函數(shù)前不能使用new命令吨娜,否則會(huì)報(bào)錯(cuò)脓匿。這是因?yàn)樯傻腟ymbol是一個(gè)原始類型的值,不是對(duì)象
Symbol函數(shù)可以接受一個(gè)字符串作為參數(shù)宦赠,表示對(duì)Symbol實(shí)例的描述陪毡,主要是為了在控制臺(tái)顯示,或者轉(zhuǎn)為字符串時(shí)勾扭,比較容易區(qū)分毡琉。
// 沒有參數(shù)的情況
var s1 = Symbol();
var s2 = Symbol();
s1 === s2 // false
// 有參數(shù)的情況
var s1 = Symbol("foo");
var s2 = Symbol("foo");
s1 === s2 // false
s1和s2都是Symbol函數(shù)的返回值,而且參數(shù)相同妙色,但是它們是不相等的桅滋。
let sym = Symbol('My symbol');
"your symbol is " + sym
// TypeError: can't convert symbol to string
`your symbol is ${sym}`
// TypeError: can't convert symbol to string
Symbol 值不能與其他類型的值進(jìn)行運(yùn)算,會(huì)報(bào)錯(cuò)
箭頭函數(shù)
ES6 允許使用“箭頭”(=>)定義函數(shù)身辨,支持expression 和 statement 兩種形式丐谋。同時(shí)一點(diǎn)很重要的是它擁有詞法作用域的this值,幫你很好的解決this的指向問(wèn)題栅表,這是一個(gè)很酷的方式笋鄙,可以幫你減少一些代碼的編寫。
注意
(1)函數(shù)體內(nèi)的this對(duì)象怪瓶,就是定義時(shí)所在的對(duì)象萧落,而不是使用時(shí)所在的對(duì)象。
(2)不可以當(dāng)作構(gòu)造函數(shù)洗贰,也就是說(shuō)找岖,不可以使用new命令,否則會(huì)拋出一個(gè)錯(cuò)誤敛滋。
(3)不可以使用arguments對(duì)象许布,該對(duì)象在函數(shù)體內(nèi)不存在。如果要用绎晃,可以用 rest 參數(shù)代替蜜唾。
(4)不可以使用yield命令,因此箭頭函數(shù)不能用作 Generator 函數(shù)庶艾。
function Timer() {
this.s1 = 0;
this.s2 = 0;
// 箭頭函數(shù)
setInterval(() => this.s1++, 1000);
// 普通函數(shù)
setInterval(function () {
this.s2++;
}, 1000);
}
var timer = new Timer();
setTimeout(() => console.log('s1: ', timer.s1), 3100);
setTimeout(() => console.log('s2: ', timer.s2), 3100);
// s1: 3
// s2: 0
Timer函數(shù)內(nèi)部設(shè)置了兩個(gè)定時(shí)器袁余,分別使用了箭頭函數(shù)和普通函數(shù)。前者的this綁定定義時(shí)所在的作用域(即Timer函數(shù))咱揍,后者的this指向運(yùn)行時(shí)所在的作用域(即全局對(duì)象)颖榜。所以,3100 毫秒之后,timer.s1被更新了 3 次掩完,而timer.s2一次都沒更新噪漾。
class Animal {
constructor(){
this.type = 'animal'
}
says(say){
setTimeout( () => {
console.log(this.type + ' says ' + say)
}, 1000)
}
}
var animal = new Animal()
animal.says('hi') //animal says hi
當(dāng)我們使用箭頭函數(shù)時(shí),函數(shù)體內(nèi)的this對(duì)象且蓬,就是定義時(shí)所在的對(duì)象欣硼,而不是使用時(shí)所在的對(duì)象。
并不是因?yàn)榧^函數(shù)內(nèi)部有綁定this的機(jī)制缅疟,實(shí)際原因是箭頭函數(shù)根本沒有自己的this分别,它的this是繼承外面的,因此內(nèi)部的this就是外層代碼塊的this存淫。
Module語(yǔ)法
在 ES6 之前耘斩,社區(qū)制定了一些模塊加載方案,最主要的有 CommonJS 和 AMD 兩種桅咆。前者用于服務(wù)器括授,后者用于瀏覽器。ES6 在語(yǔ)言標(biāo)準(zhǔn)的層面上岩饼,實(shí)現(xiàn)了模塊功能荚虚,而且實(shí)現(xiàn)得相當(dāng)簡(jiǎn)單,完全可以取代 CommonJS 和 AMD 規(guī)范籍茧,成為瀏覽器和服務(wù)器通用的模塊解決方案版述。
ES6 模塊的設(shè)計(jì)思想,是盡量的靜態(tài)化寞冯,使得編譯時(shí)就能確定模塊的依賴關(guān)系渴析,以及輸入和輸出的變量。CommonJS 和 AMD 模塊吮龄,都只能在運(yùn)行時(shí)確定這些東西俭茧。比如,CommonJS 模塊就是對(duì)象漓帚,輸入時(shí)必須查找對(duì)象屬性母债。
export
ES6將一個(gè)文件視為一個(gè)模塊,上面的模塊通過(guò) export 向外輸出了一個(gè)變量尝抖。一個(gè)模塊也可以同時(shí)往外面輸出多個(gè)變量毡们。
// profile.js
//寫法一:
export var firstName = 'Michael';
export var lastName = 'Jackson';
export var year = 1958;
//寫法二:
export var firstName = 'Michael';
export var lastName = 'Jackson';
export var year = 1958;
export {firstName, lastName, year};
import命令
定義好模塊的輸出以后就可以在另外一個(gè)模塊通過(guò)import引用。
//index.js
import {name, age} from './profile.js'
default
不用關(guān)系模塊輸出了什么昧辽,通過(guò) export default 指令就能加載到默認(rèn)模塊漏隐,不需要通過(guò) 花括號(hào)來(lái)指定輸出的模塊,一個(gè)模塊只能使用 export default 一次
// default 導(dǎo)出
export default class { ... }
// 導(dǎo)入的時(shí)候不需要花括號(hào)
import test from './test.js';