ECMAScript 6

  • A+
所属分类:Web前端
摘要

在讲解 let、const 之前,先来了解下 var。var 声明语句声明一个变量,并可选地将其初始化为一个值。


var、let、const

var

在讲解 let、const 之前,先来了解下 var。

var 声明语句声明一个变量,并可选地将其初始化为一个值。

  1. var 用以声明变量;
  2. var 声明的变量,不存在块级作用域,在全局范围内都有效;
  3. var 存在变量提升现象,因此 var 定义的变量可以先使用,后声明;

example one:

function fn() {   var a = 1   console.log(a)    // 1 } fn() 

example two:

function fn() {   if (true) {     console.log(a)    // undefined   } else {     var a = 1   } } fn() 

上面这段代码打印出 undefined 是因为 var 变量提升,代码等价于:

function fn() {   var a   if (true) {     console.log(a)   } else {     a = 1   } } fn() 

example three:
现在有如下代码,如何只暴露 fn 一个全局变量呢?

var a = 1 window.fn1 = function() {   console.log(a) } 

因为var a = 1会产生一个全局变量 a

假如我们把代码包裹在一个函数里,代码如下:

function fn2() {   var a = 1   window.fn1 = function() {     console.log(a)   } } 

如果像上面这样,a 虽然是局部变量了,但是呢,这个函数有名字 fn2,也是一个全局变量

所以使用立即执行函数,代码如下:

(function() {   var a = 1   window.fn1 = function() {     console.log(a)   } }()) 

但是这段代码太麻烦了,在ES6中,使用let就可以很方便解决此问题!

let

let 语句声明一个块级作用域的本地变量,并且可选的将其初始化为一个值。

  1. let 关键字用来声明变量;
  2. let 关键字声明的变量不能重复声明;
  3. 存在块级作用域,只在其声明的块或子块中可用;
  4. 不存在变量提升,只可以先声明,后使用;
  5. let 声明的变量存在暂时性死区,只要块级作用域中存在 let,那么它所声明的变量就绑定了这个区域,不再受外部的影响;

example one:

{   let a = 1   console.log(a)    // 1     {       let a = 2       console.log(a)    // 2     } } 

example two:

{   let a = 1   console.log(a)    // 1     {       console.log(a)    // 报错       let a = 2     } } 

example three:

{   let a = 1   console.log(a)    // 1   let a = 2    // 报错,a已经声明 } 

const

const 关键字用来声明常量,常量是块级作用域,很像使用 let 语句定义的变量。常量的值不能通过重新赋值来改变,并且不能重新声明。

  1. const 在声明时必须赋予初始值,一旦声明,其声明的值就不允许改变,更不允许重复声明;
  2. const 用于声明只读的常量;
  3. 存在块级作用域,只在其声明的块或子块中可用;
  4. 标识符一般为大写;
  5. 不存在变量提升,只可以先声明,后使用;
  6. const 声明的变量存在暂时性死区,只要块级作用域中存在 const,那么它所声明的变量就绑定了这个区域,不再受外部的影响;

example one:

{   const a = 1   console.log(a)    // 1   a = 2    // 报错 } 

example two:

const arr = [1, 2, 3] arr[0] = 2 console.log(arr)    // [2, 2, 3]  const obj = {   name: 'zww',   age: 18 } obj.name = 'lq' console.log(obj)    // {name: "lq", age: 18} 

注意:对于数组和对象的元素修改,不算做对常量的修改,不会报错。

相关题目

Question One

var a = 1  function fn() {     console.log(a)   }  ? ? ? ?  fn() 

答:

var a = 1  function fn() {   console.log(a)    // 2 } a = 2 fn() 

Question Two

下面代码将打印什么?

for (var i = 0; i < 5; i++) {} console.log(i) 

答:
以上代码等价于:

var i for (i = 0; i < 5; i++) {} console.log(i)    // 5 

Question Three

下面代码将打印什么?

for (var i = 0; i < 5; i++) {   function fn() {     console.log(i)   }   button.onclick = fn } console.log(i) 

答:都将打印5

Question Four

点击第三个li将打印什么,如何解决此问题?

var liTags = document.querySelectorAll('li')    // 假设只有6个li for (var i = 0; i < liTags.length; i++) {   liTags[i].onclick = function() {     console.log(i)   } } 

答:不管点击哪个li都将打印出6!

method one:

var liTags = document.querySelectorAll('li') for (var i = 0; i < liTags.length; i++) {   let j = i   liTags[j].onclick = function() {     console.log(j)   } } 

method two:

var liTags = document.querySelectorAll('li') for (var i = 0; i < liTags.length; i++) {   (function(j) {     liTags[j].onclick = function() {       console.log(j)     }   })(i) } 

method three:

var liTags = document.querySelectorAll('li') for (let i = 0; i < liTags.length; i++) {   liTags[i].onclick = function() {     console.log(i)   } } 

参考资料

阮一峰 - let和const命令

MDN - var

MDN - let

MDN - const

知乎 - 我用了两个月的时间才理解let

变量的解构赋值

ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构赋值。

数组的解构赋值

let name = ['zww', 'lq', 'lqzww'] let [a, b, c, d] = name console.log(a, b, c, d);    // zww lq lqzww undefined 

对象的解构赋值

let info = {   name: 'zww',   age: 18,   like: function() {     console.log("game");   } } let { name, age, like } = info console.log(name, age, like);    // zww 18 ƒ () like()    // game 

字符串的解构赋值

字符串也可以解构赋值。这是因为此时,字符串被转换成了一个类似数组的对象。

let str = 'hello' let [a, b, c, d, e, f] = str console.log(a, b, c, d, e, f)    // h e l l o undefined  let { length: len } = str console.log(len)    // 5 

模板字符串

模板字符串是字符串的增强版写法,用反引号(`)标识。它可以当作普通字符串使用,也可以用来定义多行字符串,或者在字符串中嵌入变量。

  1. 模板字符串中可以出现换行符;
  2. 可以使用 ${xxx} 的形式嵌入变量;
  3. 模板字符串中还能调用函数;
let str = `我也是字符串` console.log(str, typeof str);    // 我也是字符串 string  let name = `<ul><li>a</li><li>b</li></ul>`  let like = 'game' let out = `${like}喜欢` console.log(out);    // game喜欢  function fn() {   console.log("fn") } `${fn()}`    // fn 

简化对象的写法

ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法。这样的书写更加简洁。

let name = 'zww' let change = function() {   console.log('change'); } let info = {   name,   change,   like() {     console.log('game');   } } console.log(info);    // {name: "zww", change: ƒ, like: ƒ} 

扩展运算符

扩展运算符(spread)是三个点(...)。它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列,对数组进行解包。

let name = ['zww', 'lq', 'lqzww']  function fn() {   console.log(arguments)    // Arguments [Array(3), callee: ƒ, Symbol(Symbol.iterator): ƒ]   console.log(...arguments)    // (3) ["zww", "lq", "lqzww"] } fn(name) 
// 扩展运算符可用于数组的合并 let name = ['zww', 'lq', 'lqzww'] let age = [18, 20] var info = [...name, ...age] console.log(info)    // (5) ["zww", "lq", "lqzww", 18, 20] 
// 扩展运算符可用于数组的克隆 - 浅拷贝 let name = ['zww', 'lq', 'lqzww'] let copyName = [...name] console.log(copyName)    // (3) ["zww", "lq", "lqzww"] 
// 扩展运算符可将伪数组转为真正的数组 <div></div> <div></div>  var div = document.querySelectorAll("div") var arrDiv = [...div] console.log(div)    // NodeList(2) [div, div] console.log(arrDiv)    // (2) [div, div] 

函数的扩展

函数参数默认值

ES6 允许为函数的参数设置默认值,即直接写在参数定义的后面。

function add(a, b) {   return a + b; } console.log(add(1, 2));    // 3 console.log(add(1));    // NaN 
function add(a, b = 10) {   return a + b; } console.log(add(1, 2));    // 3 console.log(add(1));    // 11 

rest参数

ES6 引入 rest 参数(形式为...变量名),用于获取函数的多余参数,用来代替 arguments,rest 参数搭配的变量是一个数组,该变量将多余的参数放入数组中。

function fn(...args) {   console.log(args) } fn(1, 2)    // (2) [1, 2] 
function fn(a, b, ...args) {   console.log(args) } fn(1, 2, 3, 4, 5)    // (3) [3, 4, 5] 

注意:rest 参数必须要放到参数最后。

箭头函数

ES6 允许使用“箭头”(=>)定义函数。

let fn1 = function() {} // 等价于 let fn2 = () => {} 
// 简写形式 var f = x => n * n var f = (x, y) => x + y var f = (x, y) => {   return x + y } 
// 箭头函数 this 指向声明时所在作用域下 this 的值 let fn1 = function() {   console.log(this.name); } let fn2 = () => {   console.log(this.name); }  var name = 'zww'; const home = {   name: "home" }  fn1()    // zww fn2()    // zww  fn1.call(home)    // home fn2.call(home)    // zww 
// 箭头函数不能作为构造函数实例化 let Person = name => {   this.name = name; } let person = new Person('zww'); console.log(person);    // 报错:Person is not a constructor 
// 箭头函数不能使用 arguments let fn = () => {   console.log(arguments); } fn(1, 2);    // 报错:arguments is not defined 

总结:

  1. 如果形参只有一个,那么小括号可以省略;
  2. 函数体如果只有一条语句,则花括号可以省略,函数的返回值为该条语句的执行结果;
  3. 箭头函数 this 指向声明时所在作用域下 this 的值;
  4. 箭头函数不能作为构造函数实例化,也就是说,不可以使用new命令,否则会抛出一个错误。
  5. 不能使用 arguments,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。

数值的扩展

二进制和八进制表示法

ES6 提供了二进制和八进制数值的新的写法,分别用前缀 0b(或0B)和 0o(或0O)表示。

如果要将 0b 和 0o 前缀的字符串数值转为十进制,要使用 Number 方法。

let b = 0b111; console.log(b)   // 7  let o = 0o234; console.log(o)   // 156  let x = 0xabc; console.log(x)   // 2748  console.log(Number('0b111'))   // 7 console.log(Number('0o10'))   // 8 

Number.EPSILON

ES6 在 Number 对象上面,新增一个极小的常量 Number.EPSILON。它表示 1 与大于 1 的最小浮点数之间的差。

Number.EPSILON 实际上是 JavaScript 能够表示的最小精度。误差如果小于这个值,就可以认为已经没有意义了,即不存在误差了。

Number.EPSILON 的实质是一个可以接受的最小误差范围。

function equal(a, b) {   if (Math.abs(a - b) < Number.EPSILON) {     return true;   } else {     return false;   } } console.log(0.1 + 0.2 === 0.3)   // false console.log(equal(0.1 + 0.2, 0.3))   // true 

Number.isFinite() 与 Number.isNaN()

Number.isFinite() 用来检查一个数值是否为有限的(finite),即不是 Infinity。如果参数类型不是数值,Number.isFinite 一律返回 false。

Number.isNaN() 用来检查一个值是否为 NaN。如果参数类型不是 NaN,Number.isNaN 一律返回 false。

console.log(Number.isFinite(1))   // true console.log(Number.isFinite(1 / 0))   // false console.log(Number.isFinite(Infinity))   // false console.log(Number.isFinite(-Infinity))   // false  console.log(Number.isNaN(1))   // false console.log(Number.isNaN(NaN))   // true console.log(Number.isNaN(NaN / 0))   // true console.log(Number.isNaN('true' / 0))   // true console.log(Number.isNaN('true' / 'true'))   // true 

Number.parseInt() 与 Number.parseFloat()

ES6 将全局方法 parseInt() 和 parseFloat(),移植到 Number 对象上面,行为完全保持不变。

console.log(Number.parseInt('1.34abc'))   // 1 console.log(Number.parseFloat('1.34abc'))   // 1.34 

Number.isInteger()

Number.isInteger() 用来判断一个数值是否为整数。

console.log(Number.isInteger(123))   // true console.log(Number.isInteger(1.34))   // false 

Math.trunc()

Math.trunc 方法用于去除一个数的小数部分,返回整数部分。

console.log(Math.trunc(123))   // 123 console.log(Math.trunc(1.34))   // 1 

Math.sign()

Math.sign 方法用来判断一个数到底是正数、负数、还是零。对于非数值,会先将其转换为数值。

它有如下五种返回值:

  1. 参数为正数,返回 +1;
  2. 参数为负数,返回 -1;
  3. 参数为 0,返回 0;
  4. 参数为 -0,返回 -0;
  5. 其他值,返回 NaN。
console.log(Math.sign(0))   // 0 console.log(Math.sign(-0))   // -0 console.log(Math.sign(1))   // 1 console.log(Math.sign(-1))   // -1 console.log(Math.sign(NaN))   // NaN 

对象新增的方法

Object.is()

Object.is() 它是用来比较两个值是否严格相等,返回true / false,与严格比较运算符(===)的行为基本一致。

Object.is() 方法如果满足以下条件则两个值相等:

  1. 都是undefined;
  2. 都是null;
  3. 都是true或false;
  4. 都是相同长度的字符串且相同字符按相同顺序排列;
  5. 都是相同对象(意味着每个对象有同一个引用);
  6. 都是数字且都是+0;都是-0;都是NaN;或都是非零而且非 NaN且为同一个值;
Object.is('hello','hello')    // true Object.is('hello','hi')   // false  Object.is([],[])    // false  Object.is(null,null)    // true Object.is(null,undefined)   // false  Object.is(0,+0)   // true Object.is(0,-0)   // false Object.is(-0,+0)    // false Object.is(NaN,0/0)    // true 

Object.assign()

Object.assign() 方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)。

Object.assign() 方法的第一个参数是目标对象,后面的参数都是源对象。

let obj1 = {   name: 'zww',   age: 18,   like: 'game' } let obj2 = {   name: 'lq',   age: 111,   size: 22 } console.log(Object.assign(obj1, obj2))    // {name: "lq", age: 111, like: "game", size: 22} 

注意:

  1. 如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性;
  2. 如果只有一个参数,Object.assign() 会直接返回该参数;
  3. 如果该参数不是对象,则会先转成对象,然后返回;
  4. 由于 undefined 和 null 无法转成对象,所以如果它们作为参数,就会报错;
  5. Object.assign() 方法实行的是浅拷贝,而不是深拷贝,也就是说,如果源对象某个属性的值是对象,那么目标对象拷贝得到的是这个对象的引用;

该方法有如下常见用途:

  1. 为对象添加属性
  2. 为对象添加方法
  3. 克隆对象
  4. 合并多个对象
  5. 为属性指定默认值

Object.setPrototypeOf()、Object.getPrototypeOf()

Object.setPrototypeOf():用来设置一个对象的原型对象(prototype),返回参数对象本身。

Object.getPrototypeOf():用于读取一个对象的原型对象。

let a = {   name: 'zww' } let b = {   age: 18 } console.log(Object.setPrototypeOf(a, b))    // {name: "zww"} console.log(Object.getPrototypeOf(a))    // {age: 18} 

Object.keys()、Object.values()、Object.entries()

Object.keys()

ES5 引入了 Object.keys 方法,返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键名。

ES2017 引入了跟 Object.keys 配套的 Object.values 和 Object.entries,作为遍历一个对象的补充手段,供 for...of 循环使用。

var obj = {   name: 'zww',   age: 22 }; console.log(Object.keys(obj))    // (2) ["name", "age"] 

Object.values()

Object.values 方法返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键值,它只返回对象自身的可遍历属性。

var obj = {   name: 'zww',   age: 22 }; console.log(Object.values(obj))    // (2) ["zww", 22] 

Object.entries()

Object.entries() 方法返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键值对数组。

var obj = {   name: 'zww',   age: 22 }; console.log(Object.entries(obj))    // (2) [Array(2), Array(2)] 

Object.entries 方法的另一个用处是,将对象转为真正的 Map 结构。

Symbol

ES6 引入了一种新的原始数据类型 Symbol,表示独一无二的值。它是JavaScript 语言的第七种数据类型,前六种是:undefined、null、布尔值(Boolean)、字符串(String)、数值(Number)、对象(Object)。

// 通过 Symbol() 创建 let s = Symbol() console.log(s, typeof s)    // Symbol() "symbol"  let s1 = Symbol('zww') let s2 = Symbol('zww') console.log(s1 == s2)    // false console.log(s1 === s2)    // false 
// 通过 Symbol.for() 创建 let s = Symbol.for('1') console.log(s, typeof s)    // Symbol(1) "symbol"  let s1 = Symbol.for('zww') let s2 = Symbol.for('zww') console.log(s1 == s2)    // true console.log(s1 === s2)    // true 
// 对象添加 Symbol 类型的两种方式 // 第一种 let info = {   name: 'zww',   like: function() {} }  let myInfo = {   like: Symbol() }  info[myInfo.like] = function() {   console.log('hh') } console.log(info)    // {name: "zww", like: ƒ, Symbol(): ƒ}  // 第二种 let game = {   name: 'tlbb',   [Symbol('ts')]: function() {},   [Symbol('em')]: function() {} } console.log(game)    // {name: "tlbb", Symbol(ts): ƒ, Symbol(em): ƒ} 

注意:

  1. Symbol 的值是唯一的,用来解决命名冲突的问题
  2. Symbol 值不能与其他数据进行运算
  3. Symbol 定义的对象属性不能使用 for…in 循环遍历,但是可以使用 Reflect.ownKeys 来获取对象的所有键名

阮一峰 - Symbol

迭代器

遍历器(Iterator)就是这样一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作(即依次处理该数据结构的所有成员)。

Iterator 的作用有三个:一是为各种数据结构,提供一个统一的、简便的访问接口;二是使得数据结构的成员能够按某种次序排列;三是 ES6 创造了一种新的遍历命令for...of循环,Iterator 接口主要供for...of消费。

原生具备 Iterator 接口的数据(可用 for of 遍历)的有:Array、Arguments、Set、Map、String、TypedArray、NodeList。

let arr = [1, 2, 3]  for (let i of arr) {   console.log(i)    // 1 2 3 } 

Iterator 的工作原理如下:

  1. 创建一个指针对象,指向当前数据结构的起始位置;
  2. 第一次调用对象的 next 方法,指针自动指向数据结构的第一个成员;
  3. 接下来不断的调用 next 方法,指针一直往后移动,直到指向最后一个成员;
  4. 每调用 next 方法返回一个包含 value 和 done 属性的对象;
let arr = [1, 2, 3]  let iterator = arr[Symbol.iterator](); console.log(iterator)    // Array Iterator {} console.log(iterator.next());    // {value: 1, done: false} console.log(iterator.next());    // {value: 2, done: false} console.log(iterator.next());    // {value: 3, done: false} console.log(iterator.next());    // {value: undefined, done: true} 

使用迭代器可以自定义遍历数据,例如:

// 遍历 info 里的 like 数组 const info = {   name: "zww",   like: ['tlbb', 'xylm', 'wzry'],   [Symbol.iterator]() {     let index = 0;     let that = this;     return {       next: function() {         if (index < that.like.length) {           const result = {             value: that.like[index],             done: false           };           index++;           return result;         } else {           return {             value: undefined,             done: true           }         }       }     }   } }  for (let i of info) {   console.log(i);    // tlbb xylm wzry } 

阮一峰 - Iterator 和 for...of 循环

生成器

Generator 函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同。

function* gen() {   yield 'hi'   yield 'generator' } let iterator = gen() console.log(iterator)    // gen {<suspended>} console.log(iterator.next())    // {value: "hi", done: false} console.log(iterator.next())    // {value: "generator", done: false} console.log(iterator.next())    // {value: undefined, done: true} 

生成器函数可以传入参数:

function* gen(arg) {   console.log(arg)   let one =     yield 'one'   console.log(one)   let two =     yield 'two'   console.log(two) }  let iterator = gen('A') console.log(iterator.next()) console.log(iterator.next('B')) console.log(iterator.next('CCC')) 

使用生成器函数可以避免回调地狱:

function one() {   setTimeout(() => {     let data = 'tlbb'     iterator.next(data);   }, 1000) }  function two() {   setTimeout(() => {     let data = 'yxlm'     iterator.next(data);   }, 2000) }  function* gen() {   let t = yield one();   console.log(t)   let y = yield two();   console.log(y) }  let iterator = gen(); iterator.next(); 

注意:

    • 的位置没有限制,但必须在 function 与函数名之间;
  1. 生成器函数返回的结果是迭代器对象,调用迭代器对象的 next 方法可以得到 yield 语句后的值;
  2. yield 相当于函数的暂停标记,也可认为是函数的分隔符,每调用一次 next 方法,执行一段代码;
  3. next 方法可以传递实参,作为 yield 语句的返回值;

阮一峰 - Generator 函数的语法

Promise

传送门 - Promise从入门到放弃

Set

ES6 提供了新的数据结构 Set(集合)。它类似于数组,但是成员的值都是唯一的,没有重复的值(自带去重)。它实现了 iterator 接口,所以可以使用扩展运算符、for...of。

Set 本身是一个构造函数,用来生成 Set 数据结构。

let s = new Set() console.log(s, typeof s)   // Set(0) {} "object" 

Set 结构的实例具有以下几个属性:

  1. Set.prototype.constructor:构造函数,默认就是Set函数;
  2. Set.prototype.size:返回 Set 实例的成员总数;

Set 实例的方法分为两大类,分别为操作方法遍历方法

操作方法如下:

  1. .add(value):用于添加某个值,返回 Set 结构本身;
  2. .delete(value):用于删除某个值,返回的是布尔值,表示是否删除成功;
  3. .has(value):用于检测该值是否为 Set 成员,返回一个布尔值;
  4. .clear():用于清除 Set 所有成员,没有返回值;
let s = new Set([1, 2, 3, 2, 1]) console.log(s)   // Set(3) {1, 2, 3} console.log(s.size)   // 3  console.log(s.add(4))   // Set(4) {1, 2, 3, 4}  console.log(s.delete(1))   // true console.log(s)   // Set(3) {2, 3, 4}  console.log(s.has(2))   // true  s.clear() console.log(s)   // Set(0) {} 

遍历方法如下:

  1. .keys():返回键名的遍历器;
  2. .values():返回键值的遍历器;
  3. .entries():返回键值对的遍历器;
  4. .forEach():使用回调函数遍历每个成员;

注意:Set 的遍历顺序就是插入顺序。

阮一峰 - ECMAScript6入门 - Set

Map

ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。也就是说,Object 结构提供了“字符串—值”的对应,Map 结构提供了“值—值”的对应,是一种更完善的 Hash 结构实现。它也实现了 iterator 接口,所以可以使用扩展运算符、for...of。

let m = new Map() console.log(m, typeof m)   // Map(0) {} "object" 

Map 结构的实例具有以下属性和操作方法:

  1. .size:返回 Map 结构的成员总数;
  2. .set(key, value):设置键名 key 对应的键值为 value,返回整个 Map 结构。如果key已经有值,则键值会被更新,否则就新生成该键。set 方法返回的是当前的 Map 对象,因此可以采用链式写法;
  3. .get(key):读取 key 对应的键值,如果找不到 key,返回 undefined;
  4. .has(key):表示某个键是否在当前 Map 对象之中,返回一个布尔值;
  5. .delete(key):删除某个键,返回 true。如果删除失败,返回 false;
  6. .clear():清除所有成员,没有返回值;
let m = new Map()  m.set("name", "zww") m.set("like", function() {   console.log("game") }) console.log(m)   // Map(2) {"name" => "zww", "like" => ƒ}  console.log(m.size)   // 2  console.log(m.get("name"))   // zww console.log(m.get("age"))   // undefined  console.log(m.has("name"))   // true  console.log(m.delete("like"))   // true console.log(m)   // Map(1) {"name" => "zww"}  m.clear() console.log(m)   // Map(0) {} 

阮一峰 - ECMAScript6入门 - Map

class - 待完善

模块化

模块功能主要由两个命令构成:export 和 import。export 命令用于规定模块的对外接口,import 命令用于输入其他模块提供的功能。

export 暴露模块的三种方法:

  1. 分别暴露;
  2. 统一暴露;
  3. 默认暴露;
// 1. 分别暴露 export var name = 'zww'; export function like() {   console.log("like"); }  // 2. 统一暴露 var name = 'zww';  function like() {   console.log("like"); } export { name, like }  // 3. 默认暴露 export default {   name: 'zww',   like: function() {     console.log("like");   } } 

import 引入模块的三种方式:

  1. 通用方式;
  2. 解构赋值形式;
  3. 简便形式,只适用于默认暴露;
// 1. 通用方式 import * as m from './module.js'  // 2. 解构赋值形式 import { name, like } from './module.js' import { name as myname, like } from './module.js'    // 如果重名,可以使用 as 来别名 import { default as m } from './module.js'  // 3. 简便形式 import m from './module.js' 

注意:在引入模块时,要在 script 标签写上 type="module"。

参考链接

阮一峰 - ECMAScript6入门

尚硅谷 - ES6教程