前言:ES6学习总结
好吧ES8都出来了,我还在学ES6,没事的,我皮厚~
1、Set
Set是ES6新加的一种数据结构,类似数组,Set本身是个构造函数,用来生成Set数据结构,new Set()有个特点**成员值唯一,无重复的值(敲黑板)**,这一特性在数组去重的时候非常好用。
1.Set构造函数接受数组作为参数
2.Array.from方法可以将 Set 结构转为数组。// 去除数组的重复成员const arr1 = [1,3,5,3,1]const set = new Set(arr1);[...set]// [1, 3, 5] ...是ES6展开运算符const arr2 = Array.from(set);//arr1:[1,3,5,3,1]//arr2:[1,3,5]
属性:
Set.prototype.constructor:构造函数,默认就是Set函数。Set.prototype.size:返回Set实例的成员总数。
方法:
-
操作方法
add(value):添加某个值,返回Set结构本身。delete(value):删除某个值,返回一个布尔值,表示删除是否成功。has(value):返回一个布尔值,表示该值是否为Set的成员。clear():清除所有成员,没有返回值。
-
遍历方法
keys():返回键名的遍历器values():返回键值的遍历器entries():返回键值对的遍历器forEach():使用回调函数遍历每个成员
2、Map
类似于对象,是键值对的集合,但是‘键’不限字符串,可以是‘值-值’对应,Map构造函数可以接受双元素数组的数据结构作为参数,比如array、Set。1.size--返回Map成员总数2.set(key,value)set方法设置键名key对应的键值为value,然后返回整个 Map 结构。如果key已经有值,则键值会被更新,否则就新生成该键。3.get(key)get方法读取key对应的键值,如果找不到key,返回undefined。4.has(key)has方法返回一个布尔值,表示某个键是否在当前 Map 对象之中。5.delete(key)delete方法删除某个键,返回true。如果删除失败,返回false。6.clear()--clear方法清除所有成员,没有返回值.
遍历方法
keys():返回键名的遍历器。values():返回键值的遍历器。entries():返回所有成员的遍历器。forEach():遍历 Map 的所有成员。
与其他数据结构相互转换
Map <==> 数组Map <==> 对象Map <==> JSON具体操作方法见API
3.Module语法
Module即模块,其实模块化跟前后端分离出发点是一样的,解耦,提高开发效率,代码易维护及二次开发
两个命令:import 和 export 输入和输出
export命令可以输出模块,供其他模块调用,
// a.jsexport var name1 = 'zhangsan';const name2 = 'lisi'//b.jsimport {a} from 'a.js';console.log(name1,name2); //zhangsan/undefiled
除了变量还可以输出函数、类(class)
输出的时候可以用as取别名方便区分使用import命令可以引入其他模块,调用其他模块输出的变量、函数、类,
引入的时候同样可以as取别名方便区分使用import { schoolName as name1 } from './a';另外:import命令具有提升效果,会提升到整个模块的头部,首先执行。但是,在头部统一import是个好习惯,import是静态执行,所以不能使用表达式和变量,不允许运行时改变例子:{import { 'a' + 'b' } from 'a';//报错
}
模块整体加载
import * as obj from './a';
用(*)号指定一个对象,再用as取别名,所有输出值都在这个对象上面
export default命令
export default命令为模块指定默认输出;
这句话的意思就是,默认输出一个default变量,这个变量包含你写的变量方法等等,使用的时候不需要记住export的变量名和函数名等,import之后就可以直接使用了。
打个比方://a.jsexport const A;const B;export const C;//c.jsexport default{ const D,E,F; AAA(){ ... }}//b.jsimport {a} from './a';import c from './c'console.log(D,E,F); //trueAAA();//true
注意下import a、c 的区别,export default后再引入就不需要{}号了
不想暴露给其他模块的方法可以写在export default外面;export 与 import 复合写法
export { aa, bb } from './a';等同于先引入aa、bb再输出aa、bb
接口改名,整体输出也可以用复合写法
// 接口改名export { foo as myFoo } from 'my_module';// 整体输出export * from 'my_module';
模块的继承
看到继承就想起刚才的export 和 import的复合使用,先引入再输出不就继承了吗,
//b.jsexport * from './a';
但是,export * 命令会忽略a.js模块的default方法,所以必须改名后输出
跨模块常量
这块没什么好说的,直接搬代码
// constants.js 模块export const A = 1;export const B = 3;export const C = 4;// test1.js 模块import * as constants from './constants';console.log(constants.A); // 1console.log(constants.B); // 3// test2.js 模块import {A, B} from './constants';console.log(A); // 1console.log(B); // 3
如果常量较多,创建一个专门放常量的目录,里面存储各种放常量的文件
import()
前面说过,import是静态加载,但是require是运行时加载模块,所以引入import()方法来进行运行时加载,接受一个参数,就是指定要加载的模块的路径,支持变量、计算、表达式等等,
相较require,import()是异步,require是同步。
import()可以在需要时加载,不会像import那样首先执行,满足按需加载、条件加载、动态路径加载。4.Module 的加载实现
浏览器加载
浏览器通过script标签加载JavaScript
//渲染完执行//下载完立即执行,
设置type="module"浏览器会知道这是一个ES6模块,等同于打开script的defer属性。当然,也可以设置成anysc属性,
模块中引入其他模块不可省略.js后缀,vue可以因为它做了处理。模块中,顶层的this关键字不是指向window而是undefined,CommonJS 模块的顶层this指向当前模块,相同模块,加载多次只执行一次,Node加载
Node有自己的CommonJs模块,并且跟ES6模块不兼容,所以分开采用各自的加载方法,一个模块只要有一行import或export就会被Node认为是ES6模块,否则CommonJs模块,如果不输出任何接口又希望被Node认为是ES6 模块可以加一句
export {}
这不是输出空对象,而是不输接口;
用import命令加载CommonJs模块,会把CommonJs的module.exports转化为export default输出,
require命令加载 ES6 模块
采用require命令加载 ES6 模块时,ES6 模块的所有输出接口,会成为输入对象的属性。
//a.jsdexport default{ const A = 1; Const B = 2;}//b.jsconst cc = require('./a.js');console(cc.defaule);
循环加载
当两个模块或两个以上模块互相依赖,模块就要相互引入加载,这种强耦合关系,容易导致递归加载,尽量避免
CommonJS 模块的循环加载;CommonJs是运行时加载,
//a.js const A = 1; var b = require('./b.js'); const AA = 11; console.log(C,CC); // 2 22 //b.js const C = 2; var a = require('./a.js'); cons CC = 22; console.log(A,AA);// 1 undefined
假设先执行a.js
AA之所以没有值,是因为当b.js执行到var a = require('./a.js');的时候,a.js只输出一个A,而不是输出全部,ES6 模块的循环加载
// a.jsimport {bar} from './b.js';console.log('a.js');console.log(bar);export let foo = 'foo';// b.jsimport {foo} from './a.js';console.log('b.js');console.log(foo);export let bar = 'bar';//输出//b.js//undefined//a.js//bar
假先执行a.js,
第一行就会进入到b.js而不会往下,到b.js的时候第一行是引入a.js,进入a.js不往下,等a.js加载完成,再从b.js第二行开始执行。参考自
有不当或者错误的地方请指正,谢谢~