初始ES6

​ ECMAScript是一种由Ecma国际(前身为欧洲计算机制造商协会,European Computer Manufacturers Association)通过ECMA-262标准化的脚本程序设计语言。这种语言在万维网上应用广泛,它往往被称为JavaScriptJScript,所以它可以理解为是JavaScript的一个标准,但实际上后两者是ECMA-262标准的实现和扩展。

从es6开始,每年发布一个版本,版本号比年份最后以为大1

ES5——2009年发布 ES6 ——2015年发布 ES7 ——2016年发布

  • TC39是推进ECMAScript发展的委员会

  • ES6兼容性:http://kangax.github.io/compat-table/es6/

  • ES6的版本变动内容最多,具有里程碑意义

  • ES6加入许多新的语法新特性,编程实现更简单、高效

完整的JavaScript实现包含三个部分:ECMAScript文档对象模型,浏览器对象模型。ECMAScript 是JavaScript的标准

(1)ECMAScript:描述了该语言的语法和基本对象。

(2)DOM:文档对象模型(DOM),描述处理网页内容的方法和接口。

(3)BOM:浏览器对象模型(BOM),描述与浏览器进行交互的方法和接口。

变量声明

let

声明变量

1
2
3
4
5
6
7
let a;

let b,c,d;

let e = 100;

let f = 123, g = 'wsjd', h;

特性

1.变量不能重复声明

1
2
let  star = ‘1’;
let star = ‘2’;

2.有块级作用域{},var没有块级作用域,只有全局,函数,eval

1
2
3
4
if{
let a = '1';
}
console.log(a); //获取不到a的值

3.不存在变量提升

1
2
console.log(b);  //报错,获取不到b的值
let b = '1';
1
2
3
4
5
6
7
8
//var存在变量提升
console.log(b); //underfined
var b = '1';

//相当于
var b;
console.log(b); //underfined
var b = '1';

4.不影响作用域链

1
2
3
4
5
6
7
{
let s = '1';
function fn(){
console.log(s); //'1'
}
fn();
}

const

声明常量

const S = ‘1’;

特性

1.一定要赋初始值

const A;

2.一般常量使用大写

3.常量的值不能修改

4.块级作用域{}

5.对于数组和对象的元素修改,不算做对常量的修改,不会报错

1
2
const  M = ['1', '2', '3'];
M.push('4');

变量的解构赋值

数组的结构

1
2
3
4
5
6
const f = ['1','2','3','4'];
let [a, b, c, d] = f;
console.log(a); //'1'
console.log(b); //'2'
console.log(c); //'3'
console.log(d); //'4'

对象的解构

1
2
3
4
5
6
7
8
9
10
11
12
13
const  z = {
name: 'zhang',
age: '18',
study: function(){
console.log("111");
}
};
let {name, age, study} = z;
console.log(name); //'zhang'
console.log(age); //'18'
console.log(study); // function(){console.log("111");}
study();
//需要同名索引赋值

模板字符串

ES6引入新的声明字符串方式:``(反引号),以前的声明方式有 ‘’,””,

声明

1
let str = `adb`;

特性

1.内容中可以直接出现换行符(), ‘’,””不能出现

1
2
3
4
5
6
let str = `<ul>
<li>a</li>
<li>a</li>
<li>a</li>
<li>a</li>
</ul>`

变量拼接 ${}

1
2
3
let a = "hello";
let b = `${a} world`;
console.log(b); //hello world

简化写法

对象简化写法

1
2
3
4
5
6
7
8
let name = 'a';
let ab = function(){
console.log('111');
}
const s = {
name,
ab
}

函数简化写法

1
2
3
4
5
6
7
8
//原
fn: function() {

}
//现
fn(){

}

函数形参赋初值

ES6允许给函数参数赋初始值

1、形参初始值,具有默认值的参数,一般位置要靠后

1
2
3
4
5
function add(a,b,c=10) {
return a+b+c;
}
let result = add(1,2); //13
let result1 = add(1,2,3); //6

2、与解构赋值结合

1
2
3
4
5
6
7
8
9
function connect({host="127.0.0.1",username,password,port}){
console.log(host,username,password,port)
}
connect({
host: 'baidu.com',
username: 'root',
password: 'root',
port: 3306
})

箭头函数

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

声明

1
2
3
4
5
6
7
8
//原
let fn = function(a,b){

}
//现
let fn =(a,b)=> {

}

特性

1.this是静态的,this始终指向函数声明时所在作用域下的this的值

2.不能作为构造函数实例化对象

3.不能使用arguments变量(普通函数用来保存实参)

4.箭头函数简写

(1)省略小括号,当形参有且只有一个

(2)省略花括号,当代码体只有一条语句的时候,此时return必须省略,语句的执行结果就是返回值

1
let pow = n => n*n;
  • 箭头函数适合与this无关的回调,定时器,数组的方法回调
  • 不适合与this有关的回调,事件回调,对象的方法

rest参数

ES6引入rest参数,用于获取函数的实参,用来代替arguments

rest参数写法: …+参数名

arguments是对象,rest参数是数组

1
2
3
4
5
6
7
//rest参数必须放在参数最后
function fn(a,b,...args){
console.log(a); // 1
console.log(b); // 2
console.log(args); // [3,4,5,6]
}
fn(1,2,3,4,5,6)

扩展运算符

... 扩展运算符能将数组转化为逗号分割的参数序列

1
2
3
4
5
6
7
8
//声明一个数组
const tf = ['yy','wy','wjk'];

//声明一个函数
function chunwan(){
console.log(arguments);
}
chunwan(...tf); //相当于chunwan('yy','wy','wjk')

应用

1、数组的合并

1
2
3
4
const a = ['1','2'];
const b = ['3','4'];
const c = a.concat(b); //['1,'2','3','4'] es5方法
const d = [...a,...b]; //['1,'2','3','4'] es6方法

2、数组的克隆

1
2
const e = ['1','2','3'];
const f = [...e]; //['1','2','3']

如果e数组内部包含对象等引用类型,则依然是浅拷贝

3、将伪数组转为真正的数组

1
2
3
const divs = document.querySelectorAll('div');  //对象,伪数组
const divArr = [...divs];
console.log(divArr); // [div,div,div] 数组

Symbol类型

ES6引入了一种新的原始数据类型Symbol,表示独一无二的值,是一种类似于字符串的数据类型

特点

1、Symbol的值是唯一的,用来解决命名冲突的问题

2、Symbol值不能与其他数据进行运算

3、Symbol定义的对象属性不能使用for…in循环遍历,但可以使用Reflect。ownKeys来获取对象的所有键名

1
2
3
4
5
6
7
8
//创建Symbol
let s = Symbol();
//可以加一个参数,类似于注释
let s1 = Symbol('苹果'); //函数
let s2 = Symbol('苹果'); //s1 !== s2
//Symbol.for创建唯一Symbol值
let s4 = Symbol.for('土豆'); //对象
let s5 = Symbol.for('土豆'); //s4 === s5

七种基本类型:number string boolean undefined null object Symbol

作用

用来定义对象的私有属性

1
2
3
4
5
6
7
8
9
let s1 = Symbol('s1');
let obj = {
[s1]: '苹果' //Symbol类型作为对象属性名加[]
};
console.log(obj[s1]); //Symbol定义的对象中的变量,取值时一定要用[变量名]

//获取Symbol声明的属性名两种方法
let s = Object.getOwnPropertySymbols(obj);
let m = Reflect.ownKeys(obj);

Symbol内置属性

Symbol内置的属性是固定写法,整体作为对象的属性来设置,来改变

对象在特定场景的表现

迭代器

迭代器(Iterator)是一种接口,为各种不同数据提供统一的访问机制,任何数据结构只要部署Iterator接口(对象里的一个属性,属性名为Symbol.iterator),就可以完成遍历操作

1、es6创造了一种新的遍历命令for…of循环,Iterator接口主要供for…of消费

2、原生具备iterator接口的数据(可用for of遍历)

array arguments set map string typedArray nodeList

1
2
3
4
5
6
7
8
//使用for...of遍历数组
const m = ['苹果','栗子','葡萄']
for(let v of m){
console.log(v) // 苹果 //栗子 //葡萄
}
for(let v in m){
console.log(v) // 0 //1 //2
}

for...in遍历v是键名,for...of是遍历键值

1
2
3
4
5
6
7
8
9
10
Vue:
V-for循环遍历数组时,可以选择in或of结果相同,推荐使用of,语法格式为`(item,index)`
- item:迭代时不同的数组元素的值
- index:当前元素的索引
V-for循环遍历对象时推荐使用in,语法格式为`(item,name,index)`
- item:迭代时对象的键名键值
- name:迭代时对象的键名
- index:当前元素的索引
在遍历对象时,会按 `Object.keys()` 的结果遍历,但是不能保证它的结果在不同的 JavaScript 引擎下都一致。
v-for也可以在实现了可迭代协议的值上使用,包括原生的Map和Set。

3、工作原理

  • 创建一个指针对象,指向当前数据结构的起始位置
  • 第一次调用对象的next方法,指针自动指向数据结构的第一个成员
  • 不断调用next方法,指针一直向后移动直到指向最后一个成员
  • 每调用next方法返回一个包含value和done属性的对象
1
2
3
4
5
6
7
8
const m = ['苹果','栗子','葡萄'];
//Symbol.iterator是数组内置属性名,属性值是一个方法fn
let iterator = m[Symbol.iterator]();
//调用对象的next方法
console.log(iterator.next()); // {value: '苹果',done:false}
console.log(iterator.next()); // {value: '栗子',done:false}
console.log(iterator.next()); // {value: '葡萄',done:false}
console.log(iterator.next()); // {value: undefined,done:true}

迭代器应用

1、自定义遍历数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// 声明一个对象
const banji = {
name: "zz",
stus: [
'xiaom',
'xiaoy',
'xiaoz'
],
//自定义一个迭代器来自定义遍历数据
[Symbol.iterator]() {
//索引变量
let index = 0;
let self = this;
return {
next: function() {
if(index < self.stus.length){
const result = {value: self.stus[i], done: false};
index++;
return result;
}else {
return {value: underfined,done:true};
}
}
}
}
}

//遍历这个对象
for(let v of banji) {
console.log(v) // xiaom
// xiaoy
// xiaoz
}

banji.stus.forEach(); // 直接调用了其他对象内的属性,不太符合面向对象

生成器函数

生成器函数声明调用

生成器函数是ES6提供的一种异步编程解决方案

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// 生成器是一个特殊的函数
// 异步编程新的解决方案 以前 node*fs ajax MongoDB都是纯回调函数
function * gen(){
console.log('hello world')
}
//执行获取迭代器对象
let iterator = gen();
console.log(iterator) //返回一个迭代器对象,只能通过next()执行
iterator.next(); //hello world

//yield作为函数代码的分隔符,将函数分为几块
function * gen(){
console.log(111);
yield 'aaa';
console.log(222);
yield 'bbb';
console.log(333);
yield 'ccc';
console.log(444)
}
//执行获取迭代器对象
let iterator = gen();
console.log(iterator) //返回一个迭代器对象,只能通过next()执行
iterator.next(); //111
iterator.next(); //222
iterator.next(); //333
iterator.next(); //444
console.log(iterator.next()) //{value: 'aaa',done:false}
console.log(iterator.next()) //{value: 'bbb',done:false}
console.log(iterator.next()) //{value: 'ccc',done:false}
console.log(iterator.next()) //{value: underfined,done:true}

生成器函数参数传递

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//yield作为函数代码的分隔符,将函数分为几块
function * gen(arg){
console.log(arg);
let one = yield 'aaa';
console.log(one)
let two = yield 'bbb';
console.log(two)
yield 'ccc';
}
//执行获取迭代器对象
let iterator = gen('111');
console.log(iterator.next()) // 111
//{value: 'aaa',done:false}

//next方法可以传入实参
//第二次调next()方法会作为第一个yield语句的返回结果
console.log(iterator.next('222')); //222
//{value: 'bbb',done:false}
//第三次调next()方法会作为第二个yield语句的返回结果
console.log(iterator.next('333')) //333
//{value: 'ccc',done:true}

生成器函数实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
function getUsers(){
setTimeout(()=>{
let data = '用户数据';
iterator.next(data);
}, 1000);
}
function getOrders(){
setTimeout(()=>{
let data = '订单数据';
iterator.next(data);
}, 1000);
}
function getGoods(){
setTimeout(()=>{
let data = '商品数据';
iterator.next(data);
}, 1000);
}

function * gen(){
let users = yield getUsers();
console.log(users);
let orders = yield getOrders();
console.log(orders);
let goods = yield getGoods();
console.log(goods);
}
//执行获取迭代器对象
let iterator = gen();
iterator.next()

Promise

Promise是es6引入的异步编程的新解决方案,语法上Promise是一个构造函数,用来封装异步操作并可以获取其成功或失败的结果。

调用then方法,then方法的返回结果也是promise对象,对象状态由回调函数的执行结果决定,所以通过then方法可以执行链式调用

1、如果回调函数中返回的结果是非promise类型的属性,则对象状态是成功,返回值为对象成功的值

2、如果回调函数中返回的结果是promise类型的属性,则内部返回的promise对象状态决定返回对象状态

3、如果抛出错误,则返回对象状态为错误状态,返回值为抛出的错误值

1
2
3
4
5
6
7
8
9
10
11
12
13
const result = p.then(value => {
console.log(value);
// 1.非 promise类型的属性
// return '111';
// 2.是 promise对象
// return new Promise((resolve,reject)=>{
//resolve('ok')
//reject('error')
})
// 3.抛出错误
throw new Error('出错')

})

Promise链式调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<script>
var f1=function(){
return new Promise(function (resolve, reject) {
setTimeout(()=>{
let data = 'a';
resolve(data)
},1000)
})
};
var f2=function(data){
return new Promise(function (resolve, reject) {
setTimeout(()=>{
let datas = data +'b'
resolve(datas)
},1000)
})
};
var f3 = function(data){
return new Promise(function (resolve, reject) {
setTimeout(function () {
let datas = data +'c'
resolve(datas)
},1000)
})
};

f1().then(function (data) {
return f2(data);
}).then(function (data1) {
return f3(data1);
}).then(function(data2) {
console.log(data2)
}).catch(res=>{
console.log(res)
})
</script>

集合介绍和API

ES6提供了新的数据结构Set(集合),它类似于数组,但成员的值是唯一的,集合实现了iterator接口,可以使用扩展运算符和for…of遍历。

集合的属性和方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 声明一个 set
let s = new Set();
let s2 = new Set(['1','2','3']);
console.log(typeOf(s)) //object
console.log(s2) //{'1','2','3'}

//方法
//1.元素个数
console.log(s2.size);
// 2.添加新的元素
s2.add('4');
// 3.删除元素
s2.delete('1');
// 4.检测元素
console.log(s2.has('3'));
// 5.清空
s2.clear();

for(let v of s2) {
console.log(v)
}

集合的使用

1
2
3
4
5
6
7
8
9
10
11
12
let arr = [1,2,3,4,5,4,3,2,1];
// 1.数组去重
let result = [...new Set(arr)];
console.log(result); // [1,2,3,4,5]
// 2.交集
let arr2 = [4,5,6,5,6];
let result = [...new Set(arr)].filter(item => new Set(arr2).has(item))
// 3.并集
let union = [...new Set([...arr, ...arr2])];
// 4.差集
let diff = [...new Set(arr)].filter(item => !(new Set(arr2).has(item))
console.log(diff) //[1,2,3]

Map

ES6提供了新的数据结构Map,它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。Map也实现了iterator接口,所以可以使用扩展运算符和for… of 进行遍历。

属性和方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// 1.声明 Map
let m = new Map();

// 2.添加元素
m.set('name','abb');
m.set('change', function(){
console.log('111')
})
let key = {
school : 'hbg'
};
m.set(key, ['a','b'])
console.log(m);
// Map(3){
"name" => "abb",
"change" => function(){console.log('111')},
{school: 'hbg'} : ['a','b']
}

// 3.删除元素
m.delete('name');
// 4.获取
console.log(m.get('change'));
console.log(m.get(key));
// 5.清空
m.clear();
// 6.遍历、
for(let v of m){
console.log(v)
}
// 7.元素个数
m.size();

class类

ES6提供了更接近传统语言的写法,引入了class(类)的概念,作为对象的模板。通过class关键字,可以定义类。基本上ES6的class可以看作只是一个语法糖,它的绝大部分功能ES5都可以做到,新的class’写法只是让对象原型的写法更加清晰,更像面向对象编程的语法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
//ES5的方式
function Phone(brand,price){
this.brand = brand;
this.price = price;
}
//添加方法
Phone.prototype.fn = function(){
console.log('aaa')
}
//实例化对象
let Huawei = new Phone('华为'5999);
Huawei.fn();
console.log(Huawei)
//
{
brand: '华为'
price: '5999',
__proto__:{
call:fn:function(){console.log('aaa')}
}
}

// 通过class实现
class Shouji{
//构造方法,名字不能修改
constructor(brand, price){
this.brand = brand;
this.price = price;
}
//方法必须使用该方法,不能使用ES5的对象完整形式(fn:function(){})
fn() {
console.log('aaa')
}
}
let onePlus = new Shouji('1+', 1999)
console,log(onePlus)
{
brand: '1+'
price: '1999',
__proto__:{
call:fn:function(){console.log('aaa')}
}
}

class静态成员

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function Phone(){

}
Phone.name = 'shouji';
Phone.prototype.size = '5';
let nokia = new Phone();
console.log(nokia.name); //underfined
console.log(nokia.size) //5

//对于static标注的属性属于类而不属于实例对象
class Phone{
//静态属性
static name = 'shouji';
static change(){
console.log('wk');
}
}
let nokia = new Phone();
console.log(nokia.name); //underfined
console.log(Phone.name) //shouji

类继承

1、ES5对象继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
//手机
function Phone(brand, price) {
this.brand = brand;
this.price = price
}
Phone.prototype.ff = function(){
console.log('aaa')
}
function SmartPhone(brand, price, color, size){
Phone.call(this,brand,price);
this.color = color;
this.size = size
}
//设置子级构造函数的原型
SmartPhone.prototype = new Phone;
SmartPhone.prototype.constuctor = SmartPhone;

//声明子类的方法
SmartPhone.prototype.photo = function(){
console.log('111')
}
const chuzi = new SmartPhone('cz',2499,'黑色''5');
console.log(chuzi);
//
{
brand: "cz",
color: "黑色",
price: 2499,
size: "5",
__proto__ : {
brand: underfined,
consturctor: function SmartPhone(brand, price, color, size){},
photo: function(){
console.log('111')
},
price: underfined,
__proto__ : {
ff:function(){
console.log('aaa')
},
consturctor: function Phone(brand, price){},
__proto__ : Object
},
}
}

2、class的类继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
class Phone{
//构造方法
constructor(brand,price){
this.brand = brand;
this.price = price
},
//父类的成员属性
ff(){
console.log('aaa')
}
}
class SmartPhone extends Phone {
//构造方法
constructor(brand,price,color,size){
super(brand, price); //Phone.call(this,brand,price)
this.color = color;
this.size = size
}
photo(){
console.log('111')
}
}
const xiaomi = new SmartPhone('xiaomi',1499,'黑色''4');
console.log(xiaomi)
//
{
brand: "xiaomi",
color: "黑色",
price: 1499,
size: "4",
__proto__ : {
consturctor: class SmartPhone
photo: function(){
console.log('111')
},
__proto__ : {
ff:function(){
console.log('aaa')
},
consturctor: class Phone
__proto__ : Object
},
}
}

class中getter和setter设置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Phone{
get price(){
console.log("价格属性被读取了");
return '111'
}
//set需要设置一个参数
set price(newVal){
console.log("价格属性被读取了");
return '111'
}
}
// 实例化对象
let s = new Phone();
console.log(s.price); //价格属性被读取了
//111
s.price = 'free'; //价格属性被读取了

当执行获取实例对象price属性时,就会执行get的函数,并将return的值返回,执行设置price时,就会执行set的函数。

ES6的数值扩展

1、Number.EPSTION是js表示的最小精度

1
2
3
4
5
6
7
8
9
function equal(a,b){
if(Math.abs(a-b) < Number.EPSTION){
return ture;
}else{
return false
}
}
console.log(0.1+0.2 === 0.3) //false
console.log(equal(0.1+0.2,0.3)) //true

2、二进制和八进制

let b = 0b1010;

let o = 0o777;

let d = 100;

let x = 0xff;

3、Number.isFinite() 检测一个数值是否为有限数

4、Number.isNaN() 检测一个数值是否是NaN

5、Number.parseInt() Number.parseFloat()字符串转整数

6、Number.isInteger())判断一个数为整数

7、Math.trunc将数字的小数部分抹掉

8、Math.sign判断一个数到底为正数,负数还是零,返回1,0,-1

ES6对象方法扩展

1、Object.is 判断两个值是否完全相等

1
2
3
console.log(Object.is(120,120))          //true
console.log(Object.is(NaN,NaN)) //true
console.log(NaN === NaN) //false

2、Object.assign 对象的合并

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const config1 = {
host: 'localhost',
port: 3306,
name: 'aa'
}
const config2 = {
host: 'http://baidu.com',
port: 3316,
pass: 'bb'
}
console.log(Object.assign(config1, config2)) //浅拷贝合并
{
name: 'aa',
host: 'http://baidu.com',
port: 3316,
pass: 'bb'
}

3、Object.setPrototypeOf 设置原型对象 Object.getPrototypeOf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const school = {
name: 'aa'
}
const cities = {
xiaoqu: ['a','b','c']
}
Object.setPrototypeOf(school,cities); //将cities设置为school的原型对象
console.log(school);
{
name: "aa",
__proto__:{
xiaoqu: ['a','b','c'],
__proto__: Object
}
}
console.log(Object.getPrototypeOf(school)) //{xiaoqu: ['a','b','c']}

模块化

模块化是指将一个大的程序文件,拆分成许多小的文件,然后将小文件组合起来。

模块化的优点

1、防止命名冲突

2、代码复用

3、高维护性

模块化规范产品

ES6之前的模块化规范(没有自己的模块化,引用社区规范)有:

1、 CommonJS =》 NodeJS Browserify

2、 AMD =》 requireJS

3、CMD =》 seaJS

ES6模块化语法

模块功能主要由两个命令组成: import 、export

export 命令用于规定模块的对外接口

import命令用于输入其他模块提供的功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script type="module">
//引入m1.js模块内容
import * as m1 from "./m1.js"
console.log(m1.school);
m1.teach()
</script>
</body>
</html>
1
2
3
4
5
//m1.js
export let school = 'a';
export function teach() {
console.log('111')
}

ES6模块暴露语法

1、分别暴露—–上方m1.js

2、统一暴露——m2.js

1
2
3
4
5
6
7
8
9
10
//m2.js
let school = 'a';
function teach() {
console.log('111')
}
export {s, teach}
//html引用方法
import * as m2 from "./m2.js"
console.log(m2.school);
m2.teach()

3、默认暴露——–m3.js

1
2
3
4
5
6
7
8
9
10
//m3.js
export default {
school: 'a',
teach: function() {
console.log('111')
}
}
//html引用方法
import * as m3 from "./m3.js"
m3.default.teach();

ES6模块引入语法

1、通用导入方式

1
import * as m1 from "./m1.js"     //相当于把所有赋值给m1

2、解构赋值方式

1
2
3
import {school, teach} from "./m1.js"
import {school as newSchool, teach as teachfn} from "./m2.js" //若是命名冲突,使用as赋予新名字解决
import {default as m3} from "./m1.js"

3、简便形式(只能针对export default使用)

1
import m3 from "./m1.js"

babel对于ES6模块化代码转换

Babel 是一个工具链,主要用于将采用 ECMAScript 2015+ 语法编写的代码转换为向后兼容的 JavaScript 语法,以便能够运行在当前和旧版本的浏览器或其他环境中。