es6

1.let const

    let
ES6中新增let关键字,用来声明局部变量。let关键字声明的变量只在局部代码块有用,超出作用域内将不再生效, 不同于var关键字,全局有效
例如如下实例
function varAndConst() {
    let i = 10;
    var j = 12;
}
console.log(i);//提示未定义
console.log(j);//输出12

let关键字具有块级作用域,超出作用域将不在生效。因此适用于循环,判断等只在块级作用域生效的变量
例如如下实例
function sum(n) {
    let num = 0;
    for (let i = 1; i < n; n++) {
        num += i;
    }
    return num;
}

const
    constES6中用来声明一个只读的常量的关键字。
    常量一旦声明将不可更改。
    const关键字的作用域与let相同,具有块级作用域
const str = "This is const"
console.log(str)//输出 This is const
当尝试将str改变时将会执行错误
str = "change This is const"//TypeError: Assignment to constant variable.
const常量实际上指向的是常量的地址,并非引用本身。执行地址的变量值不会修改

2.解构赋值

数组结构赋值
let [i, j, k] = ["i", "j", "k"];
相当于
let i = 'i', j = 'j', k = 'k';

对象解构赋值
let { fruit, animal } = { fruit: 'apple', animal: 'dog' };
console.log(fruit);//输出apple
console.log(animal);//输出dog

字符串解构赋值
const [h, e, l, l, o] = 'hello';
h // "h"
e // "e"
l // "l"
l // "l"
o // "o"


数值和布尔值的解构和赋值
解构赋值时,如果等号右边是数值和布尔值,则会先转为对象。
let { toString: str } = 11;
str === Number.prototype.toString // true
let { toString: bool } = true;
bool === Boolean.prototype.toString // true

函数参数的解构赋值
function mod([i, j]) {
    return x / y;
}
mod([1, 2]);


3.字符串新增方法
String.fromCodePeople()
函数从 Unicode 码点返回对应字符,该方法不能识别码点大于0xFFFF的字符。

String.raw()
函数返回一个斜杠都被转义的字符串,往往用于模板字符串的处理方法。
String.raw`Hello\n${6 * 10}!`
// 实际返回 "Hi\\n5!",显示的是转义后的结果 "Hello\n60!"

includes()
函数返回布尔值,表示是否找到了参数字符串。
hello.includes("hell")//返回true

startsWith()
函数返回布尔值,表示参数字符串是否在原字符串的头部。
"hello".startsWith("h");//返回true"
"hello".startsWith("o");//返回false

endsWith()
函数返回布尔值,表示参数字符串是否在原字符串的尾部。
"hello".endsWith('o') // true
"hello".includes('h') // true

repeat方法返回一个新字符串,表示将原字符串重复n次。
'hello'.repeat(2) // "hellohello"


trimStart()
删除字符串头部的空格,

trimEnd()
删除字符串结尾的空格。

const s = '  hello  ';
s.trim() // "hello"
s.trimStart() // "hello  "
s.trimEnd() // "  hello"

matchAll()
matchAll()方法返回一个正则表达式在当前字符串的所有匹配

4.数值函数

Number.isFinite(), Number.isNaN()
Number.isFinite()用来检查一个数值是否为有限的(finite)
Number.isFinite(15); // true
Number.isFinite('Hello'); // false
Number.isNaN()用来检查一个值是否为NaN
Number.isNaN(NaN) // true
Number.isNaN(1) // false

Number.parseInt(), Number.parseFloat()
ES6 将全局方法parseInt()和parseFloat() ,移植到Number对象上面,行为完全保持不变。
// ES5的写法
parseInt('3.14') // 3
// ES6的写法
Number.parseInt('3') // 3

Number.isInteger()
Number.isInteger()用来判断一个数值是否为整数
Number.isInteger(3) // true
Number.isInteger(3.14) // false

Math.trunc()
Math.trunc()
取整函数,函数用于去除一个数的小数部分,返回整数部分。
Math.trunc(3.14) // 3

Math.sign()
函数用来判断一个数到底是正数、负数、还是零。对于非数值,会先将其转换为数值。
它会返回五种值。
参数为正数,返回 + 1;
参数为负数,返回 - 1;
参数为 0,返回0;
参数为 - 0,返回 - 0;
其他值,返回NaN。
Math.sign(-2) // -1
Math.sign(2) // +1
Math.sign(0) // +0
Math.sign(-0) // -0
Math.sign(NaN) // NaN

Math.cbrt()
函数用于计算一个数的立方根
Math.cbrt(-8) // -2
Math.cbrt(0)  // 0
Math.cbrt(1)  // 1
Math.cbrt(8)  // 2

Math.clz32()
函数将参数转为 32 位无符号整数的形式,然后返回这个 32 位值里面有多少个前导 0。
Math.clz32(0) // 32
Math.clz32(1) // 31

Math.imul()
函数返回两个数以 32 位带符号整数形式相乘的结果,返回的也是一个 32 位的带符号整数。
Math.imul(2, 4)   // 8

Math.fround()
函数返回一个数的32位单精度浮点数形式。
Math.fround(0)   // 0
Math.fround(1)   // 1

Math.hypot()
函数返回所有参数的平方和的平方根。
Math.hypot(3, 4);        // 5

Math.log1p()
函数返回1 + x的自然对数,即Math.log(1 + x) 。如果x小于 - 1,返回NaN。
Math.log1p(1)  // 0.6931471805599453
Math.log1p(0)  // 0

Math.log10()
函数返回以 10 为底的x的对数。如果x小于 0,则返回 NaN。
Math.log10(0)      // -Infinity
Math.log10(100000) // 5


Math.log2()
函数返回以 2 为底的x的对数。如果x小于 0,则返回 NaN。
Math.log2(8)    // 3


双曲函数方法
ES6 新增了 6 个双曲函数方法。
Math.sinh(x) 返回x的双曲正弦(hyperbolic sine)
Math.cosh(x) 返回x的双曲余弦(hyperbolic cosine)
Math.tanh(x) 返回x的双曲正切(hyperbolic tangent)
Math.asinh(x) 返回x的反双曲正弦(inverse hyperbolic sine)
Math.acosh(x) 返回x的反双曲余弦(inverse hyperbolic cosine)
Math.atanh(x) 返回x的反双曲正切(inverse hyperbolic tangent)

指数运算符
ES2016 新增了一个指数运算符(**)。
2 ** 2 // 4
2 ** 3 // 8


5.函数新增属性

函数参数的默认值
ES6 之前,不能直接为函数的参数指定默认值,ES6 允许为函数的参数设置默认值,如下实例
function log(x = 'Hello ', y = 'World') {
    console.log(age, sex);
}
console.log('Hello world') // Hello World

rest 参数
ES6 引入 rest 参数(形式为...变量名),用于获取函数的多余参数
function add(...values) {
    let sum = 0;

    for (var val of values) {
        sum += val;
    }

    return sum;
}
add(2, 5, 3) // 10


name 属性
函数的name属性,返回该函数的函数名
function hello() { }
hello.name // "hello"

箭头函数 最方便的数据处理函数
var sum = (i, j) => i + j;
// 等同于
var sum = function (i, j) {
    return i + j;
};


6.数组新增属性

扩展运算符
扩展运算符(spread)是三个点(...),它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列。
console.log(...["hello", " world", '!'])//hello world!

复制数组
es6以前
const a1 = [1, 2];
const a2 = a1.concat();
a2[0] = 2;
a1 // [1, 2]

es6用法
const a1 = [1, 2];
// 写法一
const a2 = [...a1];



合并数组
const arr1 = ['a', 'b'];
const arr2 = ['c'];
// ES5 的合并数组
arr1.concat(arr2);
// [ 'a', 'b', 'c' ]
// ES6 的合并数组
[...arr1, ...arr2]
// [ 'a', 'b', 'c']

字符串
[...'hello']
// [ "h", "e", "l", "l", "o" ]

Array.from()
Array.from方法用于将两类对象转为真正的数组
let arrayByObject = {
    '0': 'a',
    '1': 'b',
    '2': 'c',
};
// ES5的写法
var arr1 = [].slice.call(arrayByObject); // ['a', 'b', 'c']
// ES6的写法
let arr2 = Array.from(arrayByObject); // ['a', 'b', 'c']

Array.of()
Array.of方法用于将一组值,转换为数组。
Array.of(3, 11, 8) // [3,11,8]


find()
数组实例的find方法,用于找出第一个符合条件的数组成员。
[1, 4, -5, 10].find((n) => n > 5)
// 10

findIndex()
数组实例的findIndex返回第一个符合条件的数组成员的位置,如果所有成员都不符合条件,则返回 - 1[1, 5, 10, 15].findIndex((n) => n > 5) // 3

数组实例的 fill()
fill方法使用给定值,填充一个数组。
['any', 'any', 'any'].fill('filldata')
// ['filldata', 'filldata', 'filldata']


数组实例的 entries() ,keys()values()
entries() ,keys()和values() ——用于遍历数组。它们都返回一个遍历器对象
可以用for...of循环进行遍历,唯一的区别是keys()是对键名的遍历、values()是对键值的遍历,entries()是对键值对的遍历。

for (let index of ['1', '2'].keys()) {
    console.log(index);
}
// 0
// 1
for (let elem of ['1', '2'].values()) {
    console.log(elem);
}
// '1'
// '2'
for (let [index, elem] of ['1', '2'].entries()) {
    console.log(index, elem);
}
// 0 "1"
// 1 "2"


includes()
方法返回一个布尔值,表示某个数组是否包含给定的值,与字符串的includes方法类似。
[1, 2, 3].includes(2)     // true

数组实例的 flat()
flat()用于将嵌套的数组“拉平”,变成一维的数组。该方法返回一个新数组,对原数据没有影响。
[1, 2, [3, 4]].flat()
// [1, 2, 3, 4]




7.对象新增方法
Object.is()
ES5 比较两个值是否相等,只有两个运算符:相等运算符(==)和严格相等运算符(===)
它们都有缺点,前者会自动转换数据类型,后者的NaN不等于自身,以及 + 0等于 - 0
JavaScript 缺乏一种运算,在所有环境中,只要两个值是一样的,它们就应该相等。

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

Object.assign()
用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)。
const target = { a: 1 };
const source1 = { b: 2 };
const source2 = { c: 3 };
Object.assign(target, source1, source2);
target // {a:1, b:2, c:3}


Object.keys()
函数返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键名。
var obj = { fruit: 'apple', age: 42 };
Object.keys(obj)
// ["fruit", "age"]

Object.values()
函数返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键值。
const obj = { fruit: 'apple', age: 42 };
Object.values(obj)
// ["apple", 42]

Object.entries()
函数返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键值对数组。
const obj = { fruit: 'apple', age: 42 };
Object.entries(obj)
// [ ["fruit", "apple"], ["age", 42] ]


Object.fromEntries()
函数是Object.entries()的逆操作,用于将一个键值对数组转为对象。
Object.fromEntries([
    ['fruit', 'apple'],
    ['age', 42]
])
// { fruit: "apple", age: 42 }


8.set Map

Set
它类似于数组,但是成员的值都是唯一的,没有重复的值
Set本身是一个构造函数,用来生成 Set 数据结构
const s = new Set();
[2, 3, 5, 4, 5, 2, 2].forEach(x => s.add(x));
for (let i of s) {
    console.log(i);
}
// 2 3 5 4
上面代码通过add()方法向 Set 结构加入成员,结果表明 Set 结构不会添加重复的值。
Set函数可以接受一个数组(或者具有 iterable 接口的其他数据结构)作为参数,用来初始化。
Set 实例的属性和方法
Set.prototype.constructor:构造函数,默认就是Set函数。
Set.prototype.size:返回Set实例的成员总数。
Set 实例的方法分为两大类:操作方法(用于操作数据)和遍历方法(用于遍历成员)。下面先介绍四个操作方法。
Set.prototype.add(value) :添加某个值,返回 Set 结构本身。
Set.prototype.delete(value) :删除某个值,返回一个布尔值,表示删除是否成功。
Set.prototype.has(value) :返回一个布尔值,表示该值是否为Set的成员。
Set.prototype.clear() :清除所有成员,没有返回值。
遍历操作
Set 结构的实例有四个遍历方法,可以用于遍历成员。
Set.prototype.keys() :返回键名的遍历器
Set.prototype.values() :返回键值的遍历器
Set.prototype.entries() :返回键值对的遍历器
Set.prototype.forEach() :使用回调函数遍历每个成员
(1)keys() ,values() ,entries()
keys方法、values方法、entries方法返回的都是遍历器对象
由于 Set 结构没有键名,只有键值(或者说键名和键值是同一个值)所以keys方法和values方法的行为完全一致
let set = new Set(['am', 'is', 'are']);
for (let item of set.keys()) {
    console.log(item);
}
// am
// is
// are
for (let item of set.values()) {
    console.log(item);
}
// am
// is
// are
for (let item of set.entries()) {
    console.log(item);
}
// ["am", "am"]
// ["is", "is"]
// ["are", "are"]



Map
JavaScript 的对象(Object),本质上是键值对的集合(Hash 结构),但是传统上只能用字符串当作键。这给它的使用带来了很大的限制
Map类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。
const m = new Map();
const o = { p: 'Hello World' };
m.set(o, 'content')
m.get(o) // "content"
m.has(o) // true
m.delete(o) // true
m.has(o) // false
上面代码使用 Map 结构的set方法,将对象o当作m的一个键,然后又使用get方法读取这个键,接着使用delete方法删除了这个键。
实例的属性和操作方法
Map 结构的实例有以下属性和操作方法。
(1)size 属性
size属性返回 Map 结构的成员总数。
const map = new Map();
map.set('fruit', true);
map.set('apple', false);
map.size // 22)Map.prototype.set(key, value)
set方法设置键名key对应的键值为value,然后返回整个 Map 结构。如果key已经有值,则键值会被更新,否则就新生成该键。
const m = new Map();
m.set('edition', 6)        // 键是字符串3)Map.prototype.get(key)
get方法读取key对应的键值,如果找不到key,返回undefined。
const m = new Map();
m.set(hello, 'Hello ES6!') // 键是函数
m.get(hello)  // Hello ES6!4)Map.prototype.has(key)
has方法返回一个布尔值,表示某个键是否在当前 Map 对象之中。
const m = new Map();
m.set('edition', 6);
m.has('edition')     // true
m.has('years')       // false5)Map.prototype.delete(key)
delete方法删除某个键,返回true。如果删除失败,返回falseconst m = new Map();
m.set(undefined, 'nah');
m.has(undefined)     // true
m.delete(undefined)
m.has(undefined)       // false6)Map.prototype.clear()
clear方法清除所有成员,没有返回值。
let map = new Map();
map.set('fruit', true);
map.set('apple', false);
map.size // 2
map.clear()
map.size // 0
遍历方法
Map 结构原生提供三个遍历器生成函数和一个遍历方法。
Map.prototype.keys() :返回键名的遍历器。
Map.prototype.values() :返回键值的遍历器。
Map.prototype.entries() :返回所有成员的遍历器。
Map.prototype.forEach() :遍历 Map 的所有成员。
需要特别注意的是,Map 的遍历顺序就是插入顺序。
const map = new Map([
    ['F', 'no'],
    ['T', 'yes'],
]);
for (let key of map.keys()) {
    console.log(key);
}
// "F"
// "T"
for (let value of map.values()) {
    console.log(value);
}
// "no"
// "yes"
for (let item of map.entries()) {
    console.log(item[0], item[1]);
}
// "F" "no"
// "T" "yes"


9.promise
Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大
Promise简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果
从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理

Promise对象有以下两个特点。
(1)对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。
只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是Promise这个名字的由来,它的英语意思就是“承诺”,表示其他手段无法改变。
(2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。
只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。如果改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果。
这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。
有了Promise对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。此外,Promise对象提供统一的接口,使得控制异步操作更加容易。
基本用法
下面代码创造了一个Promise实例。

const promise = new Promise(function (resolve, reject) {
    // ... some code

    if (/* 异步操作成功 */) {
        resolve(value);
    } else {
        reject(error);
    }
});
Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject。它们是两个函数,由 JavaScript 引擎提供,不用自己部署
resolve函数的作用是,将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去
reject函数的作用是,将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去

Promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数。
promise.then(function (value) {
    // success
}, function (error) {
    // failure
});
then方法可以接受两个回调函数作为参数
第一个回调函数是Promise对象的状态变为resolved时调用
第二个回调函数是Promise对象的状态变为rejected时调用。
其中,第二个函数是可选的,不一定要提供。这两个函数都接受Promise对象传出的值作为参数。

下面是一个用户登录的Promise对象的简单例子。
function checkStatus(response) {
    return new Promise((resolve, reject) => {
        if (response.status === 200) {
            if (response.data.code === 401 && !hasConfirm) {
                hasConfirm = true;
                MessageBox.confirm('登陆超时是否重新登录?', '提示', {
                    distinguishCancelAndClose: true,
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                }).then(() => {
                    sessionStorage.removeItem('token');
                    hasConfirm = false;
                    router.push({ path: '/login' });
                    window.location.reload();
                }).catch(() => {
                    hasConfirm = false;
                });
            }
            if (response.data.code) {
                if (response.data.code == 200) {
                    resolve(response.data);
                } else if (response.data.code == 401) { } else {
                    reject(response.data);
                }
            } else {
                if (response.config.responseType == 'blob') {
                    resolve(response);
                } else {
                    resolve(response.data);
                }
            }
        } else {
            reject(response.data);
        }
    });
}

post(url, data) {
    let obj = data;

    return axios({
        method: 'post',
        url,
        data: qs.stringify(obj),
        headers: {
            'X-Requested-With': 'XMLHttpRequest',
            'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
            'Authorization': sessionStorage.getItem('token')
        }
    }).then(checkStatus);
}


10.迭代器
遍历器一种接口,为各种不同的数据结构提供统一的访问机制。通过它可以完成遍历操作
Iterator 的作用有三个:
一是为各种数据结构,提供一个统一的、简便的访问接口;
二是使得数据结构的成员能够按某种次序排列;
三是 ES6 创造了一种新的遍历命令for...of循环,Iterator 接口主要供for...of消费。
Iterator 的遍历过程是这样的。
(1)创建一个指针对象,指向当前数据结构的起始位置。也就是说,遍历器对象本质上,就是一个指针对象。
(2)第一次调用指针对象的next方法,可以将指针指向数据结构的第一个成员。
(3)第二次调用指针对象的next方法,指针就指向数据结构的第二个成员。
(4)不断调用指针对象的next方法,直到它指向数据结构的结束位置。
每一次调用next方法,都会返回数据结构的当前成员的信息。具体来说,就是返回一个包含value和done两个属性的对象。
其中,value属性是当前成员的值,done属性是一个布尔值,表示遍历是否结束。

下面是一个模拟next方法返回值的例子。
var it = makeIterator(['a', 'b']);
it.next() // { value: "a", done: false }
it.next() // { value: "b", done: false }
it.next() // { value: undefined, done: true }
function makeIterator(array) {
    var nextIndex = 0;
    return {
        next: function () {
            return nextIndex < array.length ?
                { value: array[nextIndex++], done: false } :
                { value: undefined, done: true };
        }
    };
}
上面代码定义了一个makeIterator函数,它是一个遍历器生成函数,作用就是返回一个遍历器对象。
对数组['a', 'b']执行这个函数,就会返回该数组的遍历器对象(即指针对象)it。
指针对象的next方法,用来移动指针。开始时,指针指向数组的开始位置。然后,每次调用next方法,指针就会指向数组的下一个成员。
第一次调用,指向a;第二次调用,指向b。
next方法返回一个对象,表示当前数据成员的信息。这个对象具有value和done两个属性,value属性返回当前位置的成员,
done属性是一个布尔值,表示遍历是否结束,即是否还有必要再一次调用next方法。
总之,调用指针对象的next方法,就可以遍历事先给定的数据结构。
对于遍历器对象来说,done: false和value: undefined属性都是可以省略的,因此上面的makeIterator函数可以简写成下面的形式。

function makeIterator(array) {
    var nextIndex = 0;
    return {
        next: function () {
            return nextIndex < array.length ?
                { value: array[nextIndex++] } :
                { done: true };
        }
    };
}


11.async
async 函数使得异步操作变得更加方便。
await等待右侧表达式的结果,这个结果是promise对象或者其他值。
如果它等到的不是一个 promise 对象,那 await 表达式的运算结果就是它等到的东西。
如果它等到的是一个 promise 对象,await 就忙起来了,它会阻塞后面的代码,等着 promise 对象 resolve,
然后得到 resolve 的值,作为 await 表达式的运算结果。
function test() {
    return new Promise(resolve => {
        setTimeout(() => resolve("test"), 2000);
    });
}
const result = await test();
console.log(result);
console.log('end')





12.class
JavaScript 语言中,生成实例对象的传统方法是通过构造函数。下面是一个例子。
function People(age, sex) {
    this.age = x;
    this.sex = y;
}
People.prototype.toString = function () {
    return '(' + this.age + ', ' + this.sex + ')';
};

var p = new People(1, 2);
ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。
class People {
    constructor(age, sex) {
        this.age = x;
        this.sex = y;
    }

    toString() {
        return '(' + this.age + ', ' + this.sex + ')';
    }
}
上面代码定义了一个“类”,可以看到里面有一个constructor方法,这就是构造方法,而this关键字则代表实例对象。
也就是说,ES5 的构造函数People,对应 ES6 的People类的构造方法。

People类除了构造方法,还定义了一个toString方法。注意,定义“类”的方法的时候,前面不需要加上function这个关键字,
直接把函数定义放进去了就可以了。另外,方法之间不需要逗号分隔,加了会报错。

class 可以通过extends关键字实现继承,这比 ES5 的通过修改原型链实现继承,要清晰和方便很多。

class People {
}

class ColorPeople extends People {
}
上面代码定义了一个ColorPeople类,该类通过extends关键字,继承了People类的所有属性和方法。
但是由于没有部署任何代码,所以这两个类完全一样,等于复制了一个People类。下面,我们在ColorPeople内部加上代码。

class ColorPeople extends People {
    constructor(x, y, color) {
        super(age, sex); // 调用父类的constructor(age, sex)
        this.color = color;
    }
    toString() {
        return this.color + ' ' + super.toString(); // 调用父类的toString()
    }
}

13.模块
JavaScript 一直没有模块(module)体系,无法将一个大程序拆分成互相依赖的小文件,再用简单的方法拼装起来。

在 ES6 之前,社区制定了一些模块加载方案,最主要的有 CommonJS 和 AMD 两种。前者用于服务器,后者用于浏览器。

// CommonJS模块
let { stat, exists, readfile } = require('fs');

// 等同于
let _fs = require('fs');
let stat = _fs.stat;
let exists = _fs.exists;
let readfile = _fs.readfile;

ES6 模块不是对象,而是通过export命令显式指定输出的代码,再通过import命令输入。

// ES6模块
import { stat, exists, readFile } from 'fs';
上面代码的实质是从fs模块加载 3 个方法,其他方法不加载。
这种加载称为“编译时加载”或者静态加载,即 ES6 可以在编译时就完成模块加载,效率要比 CommonJS 模块的加载方式高。
当然,这也导致了没法引用 ES6 模块本身,因为它不是对象。

由于 ES6 模块是编译时加载,使得静态分析成为可能。有了它,就能进一步拓宽 JavaScript 的语法,比如引入宏(macro)和类型检验(type system)
这些只能靠静态分析实现的功能。
除了静态加载带来的各种好处,ES6 模块还有以下好处。
    不再需要UMD模块格式了,将来服务器和浏览器都会支持 ES6 模块格式。目前,通过各种工具库,其实已经做到了这一点。
    将来浏览器的新 API 就能用模块格式提供,不再必须做成全局变量或者navigator对象的属性。
    不再需要对象作为命名空间(比如Math对象),未来这些功能可以通过模块提供。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值