簡介
ECMAScript 和 JavaScript 的關(guān)系是星虹,前者是后者的規(guī)格挣饥,后者是前者的一種實(shí)現(xiàn)自晰。
現(xiàn)在通用的是ES5(ES3)。
ES6每年都有一次更新浙宜,所以具體版本如ES2015指的是ES6的2015年版本官辽。
let和const
Let
let不同于var,let具有塊級作用域概念粟瞬,let不會提升變量同仆。
let存在暫時性死區(qū),在代碼塊內(nèi)裙品,使用let命令聲明變量之前俗批,該變量都是不可用的。這在語法上市怎,稱為“暫時性死區(qū)”(temporal dead zone岁忘,簡稱 TDZ),同樣的在死區(qū)使用typeof()也是輝報(bào)錯的区匠。
let不允許重復(fù)聲明干像。
let定義的變量不會存在于全局對象的屬性中。
const
const類似于let,const指向的內(nèi)存被鎖死麻汰,無法被改變速客。
變量的存儲分簡單和復(fù)雜,簡單類型存儲的是數(shù)據(jù)什乙,復(fù)雜類型存儲的是指針。
使用Object.freeze()對對象進(jìn)行凍結(jié)已球。
變量解構(gòu)
ES6允許按照一定模式,從數(shù)組和對象中提取值,對變量進(jìn)行賦值何吝,稱為解析宏怔。
這種模式方便解析數(shù)組和對象。
這種寫法屬于 "模式匹配" ,只要兩邊模式相等阔蛉,左邊的變量就會被賦予對應(yīng)的值弃舒。
數(shù)組解構(gòu)
數(shù)組解構(gòu)是按照排列順序的
下面的let中實(shí)際上是先定義了var1... ,
然后([var1, [var21, var23], var3] = [1, [2, 6], 3]);
let [var1, [var21, var23], var3] = [1, [2, 6], 3];
var1 : 1, var21 : 2, var23 : 6, var3 : 3
let[var1, ...var2] = [1, [2, 6], 3];
var1 : 1, var2 : [[2,6], 3]
不完全解構(gòu)
let [var1, [var21], var3] = [1, [2, 6], 3]
var1 :1,
var21 : 2,
var3 : 3
解構(gòu)賦值允許指定默認(rèn)值状原。默認(rèn)值生效的條件是聋呢,對象的屬性值嚴(yán)格等于undefined,使用函數(shù)賦值會是惰性求值颠区。
let [var1, [var21, var22 , var23 = 8 ], var3] = [1, [2, 6], 3]
var1 : 1
var21 : 2
var22 : 6
var23 : 8
var3 : 3
對象解構(gòu)
對象解構(gòu)是依據(jù)對象屬性名進(jìn)行解析的
對象的解構(gòu)賦值可以取到繼承的屬性削锰。
let {foo ,bar} = {foo : 'aaa', bar : 'ccc'};
//等于
let {foo : foo, bar : bar} = {foo : 'aaa', bar : 'ccc'}
foo : foo //前者是匹配模式,后者是賦予的變量
嵌套
let {info : {name : Name}, score : [score1, score2, score3]} =
{ info : {name : 'Name'}, score : [99 毕莱, 98 器贩,99]}
Name : 'Name'
score1 : 99
score2 : 98
score3 : 99
解構(gòu)賦值的規(guī)則 :?只要等號右邊的值不是對象或數(shù)組,就先將其轉(zhuǎn)為對象朋截。由于undefined和null無法轉(zhuǎn)為對象蛹稍,所以對它們進(jìn)行解構(gòu)賦值,都會報(bào)錯部服。但是像字符串唆姐,數(shù)組,布爾都可以廓八。
函數(shù)參數(shù)的解構(gòu)
函數(shù)的參數(shù)也可以使用解構(gòu)賦值厦酬。
function({x, y })
{
? ? //傳入的參數(shù)會被解構(gòu)
????//傳入?yún)?shù)也可以使用默認(rèn)值
? ? //也可以使用函數(shù)自帶默認(rèn)值
}
注意點(diǎn)
// 正確的寫法 let x;
({x} = {x: 1}); //必須加上括號‘
Module的語法
ES6有自帶的模塊加載方案,Node.js使用的是CommonJS的模塊加載方案瘫想。
CommonJS
CommonJS的模塊加載方案使用在服務(wù)器端仗阅。
CommonJS的關(guān)鍵詞 : require? ? Module.exports? ?export
let{stat,exists,readFile}=require('fs');
由于CommonJS輸出是值的拷貝
var counter = 3;
function incCounter() {
? counter++;
}
module.exports = {
? get counter() {
? ? return counter
? },
? incCounter: incCounter,
};
CommonJS特性
運(yùn)行時加載。
使用exports輸出的時值的拷貝国夜,而非引用减噪。
ES6模塊
ES6模塊加載方案可以在服務(wù)端和瀏覽器都運(yùn)行。
ES6的關(guān)鍵詞 : import export
export
這種方式輸出的接口名稱跟變量名一樣
//第一種
export var firstName = 'Hong';
export Class {};
export function FuncName() {};
//第二種
var firstName = 'Hong';
export {firstName};
指定輸出接口的名稱
var firstName = 'Hong';
export { firstName as fName};
默認(rèn)輸出
export default xxx;
import
JS 文件通過import命令加載模塊
輸出的接口只讀,無法修改
import {firstName} from ’./moduleName.js‘
輸出的變量重命名
import {firstName as fName} from 'xxx'
由于import是靜態(tài)執(zhí)行筹裕,所以不能使用表達(dá)式和變量醋闭,這些只有在運(yùn)行時才能得到結(jié)果的語法結(jié)構(gòu)。
import語句會執(zhí)行所加載的模塊朝卒,因此可以有下面的寫法证逻。
import 'lodash';
模塊的整體加載
export? * as obj from 'xxxx'
模塊的默認(rèn)加載
export defaultName from 'xxxx'
//加載默認(rèn)輸出
Module的加載
瀏覽器加載
瀏覽器加載ES6模塊,也使用<script>標(biāo)簽抗斤,
要加上 type = "module"屬性囚企。
瀏覽器對于帶有type="module"的<script>,都是異步加載瑞眼,不會造成堵塞瀏覽器龙宏,即等到整個頁面渲染完,再執(zhí)行模塊腳本伤疙,等同于打開了<script>標(biāo)簽的defer屬性银酗。
<script type="module" src="./foo.js"></script>
jquery就支持模塊加載。
引入的模塊特性
代碼是在模塊作用域之中運(yùn)行徒像,而不是在全局作用域運(yùn)行黍特。模塊內(nèi)部的頂層變量,外部不可見锯蛀。
模塊腳本自動采用嚴(yán)格模式衅澈,不管有沒有聲明use strict。
模塊之中谬墙,可以使用import命令加載其他模塊(.js后綴不可省略今布,需要提供絕對 URL 或相對 URL),也可以使用export命令輸出對外接口拭抬。
模塊之中部默,頂層的this關(guān)鍵字返回undefined,而不是指向window造虎。也就是說傅蹂,在模塊頂層使用this關(guān)鍵字,是無意義的算凿。
同一個模塊如果加載多次份蝴,將只執(zhí)行一次。
Node.js加載
Node.js 對 ES6 模塊的處理比較麻煩氓轰,因?yàn)樗凶约旱?CommonJS 模塊格式婚夫,與 ES6 模塊格式是不兼容的。
Node.js默認(rèn)是以CommonJS進(jìn)行加載的署鸡。
使用mjs后綴的話案糙,Node.js會以ES6的模式加載限嫌。
使用cjs后綴的話,Node.js會以CommonJS模式加載时捌。
package.json里面的type決定了默認(rèn)加載方式怒医。
type = "module"/"commonjs"。
ES6模塊
創(chuàng)建一個模塊之后
在package.json文件中使用main/export指定模塊的入口文件
main字段
// ./node_modules/es-module-package/package.json
{
? "type": "module",
? "main": "./src/index.js"
}
import命令就可以加載這個模塊奢讨。
// ./my-app.mjs
import { something } from 'es-module-package';
export字段