1.开始之前
在安装Babel之前,需要用npm init先初始化我们的项目。打开终端或者通过cmd打开命令行工具,进入项目目录,输入下边的命令:
1
|
npm init -y // 自动生成package.json文件
|
需求:如何将dist文件夹中的js将es6转化为es5编程。
1
2
3
4
|
npm install -g babel-cli
npm install --save-dev babel-preset-es2015 babel-cli
//编译命令
babel src/index.js -o dist/index.js
|
2.声明方式
ES6的三种声明方式:
- var:声明全局变量;
- let:声明局部变量,防止数据污染;
- const:声明常量,用来定义一个不可变的常量,如果改变了就会报语法错误。
VAR
1
2
3
4
5
|
var a = 'abc';
window.onload = function () {
console.log(a);
}
控制台打印出:abc,说明var声明的a是全局变量
|
LET
1
2
3
4
5
6
7
|
{
let a = 'abc';
}
window.onload = function () {
console.log(a);
}
结果:报错。说明let声明的是局部变量,它只在它所在的语句块中有用。
|
CONST
1
2
3
|
var a = "abc";
const a = "efg";
console.log(a);
|
会报语法错误:
3.解构赋值
什么是解构?ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构。
解构的作用?解构赋值在实际开发中可以大量减少我们的代码量,并且让我们的程序结构更清晰。
数组的结构赋值:
1
2
3
4
5
6
|
let a=0;
let b=1;
let c=2;
//等同于
let [a,b,c] = [0,1,2];
//按照位置的对象关系对变量赋值
|
1
2
3
|
数组模式和赋值模式统一:
可以简单的理解为等号左边和等号右边的形式要统一,如果不统一解构将失败。
|
数组函数的解构赋值
1
2
3
4
5
6
7
|
let arr = ['good','better','best'];
function fn(a,b,c) {
console.log(a); //good
console.log(b); //better
console.log(c); //best
}
fn(...arr); //...对象扩展运算符,在后面会说到
|
解构的默认值:
解构赋值是允许你使用默认值的
1
2
|
let [foo = true] =[];
console.log(foo); //控制台打印出true
|
1
2
3
|
let [a,b="world"]=['hello '];
console.log(a+b); //控制台显示“hello world”
//hello为a的值,b的默认值为world,所以显示“hello world”
|
注意:undefined 和 null的区别
1
2
3
|
let [a,b="world"]=['hello ',undefined];
console.log(a+b); //控制台显示“hello world”
//说明undefined表示空
|
1
2
3
|
let [a,b="world"]=['hello ',undefined];
console.log(a+b); //控制台显示“hello null”
//null 表示有值
|
对象的解构赋值
1
2
|
let {a,b} ={a:"abc",b:"123"};
console.log(a+b); //控制台显示:"abc123"
|
注意:对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。
对象函数的解构赋值
1
2
3
4
5
6
7
8
9
|
let json = {
a:'abc',
b: 123
};
function fn({a,b=456}) {
console.log(a); //abc
console.log(b); //123
}
fn(json);
|
es6小坑:
1
2
3
4
5
6
7
8
9
|
//当先声明了对象,然后再对象解构,这会报错
let foo;
{foo} = {foo: "abc"};
console.log(foo);
//解决方法:解构时加一个圆括号
let foo;
({foo} = {foo: "abc"});
console.log(foo); //控制台显示:abc
|
字符串的解构赋值
1
2
3
4
5
6
7
8
9
10
11
12
|
const [a,b,c,d,e]="hello";
console.log(a);
console.log(b);
console.log(c);
console.log(d);
console.log(e);
//控制台显示:
//h
//e
//l
//l
//o
|
4.对象扩展运算符和rest运算符
对象扩展运算符(…)
当编写一个方法时,我们允许它传入的参数是不确定的,这时候可以使用对象扩展运算符来作参数。
1
2
3
4
5
6
7
8
|
function fn(...arg) {
console.log(arg[0]);
console.log(arg[1]);
console.log(arg[2]);
console.log(arg[3]);
}
fn(1,2,3);
//控制台显示: 1 2 3 undefined
|
作用:用来解决数组赋值会改变原数组数据的问题。
1
2
3
4
5
|
let arr1 = ['a','b','c'];
let arr2 = arr1;
arr2.push("d");
console.log(arr2); //控制台显示:["a", "b", "c", "d"]
console.log(arr1); //控制台显示:["a", "b", "c", "d"] arr1改变了,这个是非常不好的。
|
使用对象扩展运算符后
1
2
3
4
5
|
let arr1 = ['a','b','c'];
let arr2 = [...arr1];
arr2.push("d");
console.log(arr2); //控制台显示:["a", "b", "c", "d"]
console.log(arr1); //控制台显示:["a", "b", "c"] arr1没有改变
|
REST运算符(…)
也用”…”表示
用法:
1
2
3
4
5
6
7
8
9
10
11
|
function fn(a,b,...arg) {
console.log(a); //0
console.log(b); //1
console.log(arg.length); //6
for(let val of arg){
console.log(val); //2,3,4,5,6,7
}
}
fn(0,1,2,3,4,5,6,7);
//可以看出a表示第一个值,b表示第二个值,...arg表示剩余的值
//所以a的值为0,b的值为1,...arg的值为剩余的值2,3,4,5,6,7
|
5.字符串模板
使用方法:字符串必须使用’`’(~下面的符号)包围,然后使用${变量}。
1
2
3
|
let name = 'whittney';
let str = `大家好,我是${name}`;
document.write(str);
|
字符串的方法:
1.查找是否存在:includes()
1
2
3
|
let name = 'whittney';
let str = `大家好,我是${name}`;
console.log(str.includes(name)); //true
|
2.判断开头是否存在:startsWith()
1
2
3
|
let name = 'whittney';
let str = `大家好,我是${name}`;
console.log(str.startsWith(name)); //false
|
3.判断结尾是否存在:endsWith()
1
2
3
|
let name = 'whittney';
let str = `大家好,我是${name}`;
console.log(str.endsWith(name)); //true
|
4.复制字符串:repeat()
1
2
|
let name = 'whittney';
console.log(name.repeat(3)); //whittneywhittneywhittney
|
6.数字操作
1.如何表示二进制数?
二进制的英文单词是Binary,以0(零)和b(或B)开头,后面为二进制值即可。
1
2
|
let binary = 0b0101;
console.log(binary); //5
|
2.如何表示八进制数?
八进制的英文单词是Octal,以0(零)和o(或O)开头,后面为八进制值即可。
1
2
|
let octal = 0o0032;
console.log(octal); //26
|
3.判断是否是数字
Number.isFinite( )来进行数字验证,只要是数字,不论是浮点型还是整形都会返回true,其他时候会返回false。
1
2
|
let a = 'a';
console.log(Number.isFinite(a)); //false
|
4.判断是否为整数Number.isInteger(xx)
1
2
|
let a=111.123;
console.log(Number.isInteger(a)); //false
|
5.转换为整数
1
2
|
let a= '111.123';
console.log(Number.parseInt(a)); //111
|
6.转换为浮点数
1
2
|
let a= '111.123';
console.log(Number.parseFloat(a)); //111.123
|
7.ES6中新增的数组知识
1.json数组格式是什么样的?
1
2
3
4
5
6
7
|
let json = {
'0': 'a',
'1': 'b',
'2': 'c',
length:3
}
//JSON数组格式跟普通的JSON对比是在最后多了一个length属性
|
如何将json数组转化为数组?
1
2
3
4
5
6
7
|
let json = {
'0': 'a',
'1': 'b',
'2': 'c',
}
let arr = Array.from(json);
console.log(arr); //["a", "b", "c"]
|
2.Array.of()方法
将一堆文本或者变量转换成数组
1
2
|
let arr = Array.of("abc",3,5);
console.log(arr); //["abc",3,5]
|
3.find()方法
从数组中查找元素
有三个参数:
val:表示当前查找的值;
index:表示当前查找的数组索引;
arr:表示当前数组。
1
2
3
4
5
|
let arr = [1,3,5,7,9];
console.log(arr.find(function (val,index,arr) {
return val >5;
})) //7
// 函数中如果找到符合条件的数组元素就进行return
|
4.fill()方法
数组进行填充,其实就是替换数组元素。
也有三个参数:第一个参数是要填充的内容,第二个参数是开始填充的位置,第三个是填充到的位置(不包括)。
1
2
3
|
let arr = [0,1,2,3];
arr.fill('abc',1,3);
console.log(arr); //[0, "abc", "abc", 3]
|
5.for..of循环
输出内容
1
2
3
4
|
let arr = ['a','b','c'];
for(let item of arr){
console.log(item); //a,b,c
}
|
输出索引
1
2
3
4
|
let arr = ['a','b','c'];
for(let index of arr.keys()){
console.log(index); //0,1,2
}
|
同时输出内容和索引
1
2
3
4
5
6
7
|
let arr = ['a','b','c'];
for(let [index,val] of arr.entries()){
console.log(index+':'+val);
}
//控制台输出:0:a
// 1:b
// 2:c
|
6.entries()
生成的是Iterator形式的数组,好处就是可以让我们在需要时用next()手动跳转到下一个值。
1
2
3
4
5
6
|
let arr = ['a','b','c'];
let list = arr.entries();
console.log(list.next().value); // [0, "a"]
console.log(list.next().value); // [1, "b"]
console.log(list.next().value); // [2, "c"]
//输出内容是数组,第一个值为所在arr的索引,第二只为arr中所在索引的内容。
|
7.in
判断对象或者数组中是否存在某个值。
对象判断:
1
2
3
4
5
|
let obj = {
a: 'abc',
b: 123
}
console.log('a' in obj); //true 注意:a元素要用引号
|
数组判断:
1
2
|
let arr= ['a','b'];
console.log(0 in arr); //true 注意:0表示索引,0指的是数组下标位置是否为空。
|
8.箭头函数
ES6中给我们增加了默认值的操作
1
2
3
4
|
function add(a,b=3) {
return a+b;
}
console.log(add(1)); //没有报错,显示:4
|
主动抛出错误:vue框架中就是这样抛出错误的。
1
2
3
4
5
6
7
|
function add(a,b=3) {
if(a == 0){
throw new Error("a is error");
}
return a+b;
}
console.log(add(0));
|
获得需要传递的参数个数
如果你在使用别人的框架时,不知道别人的函数需要传递几个参数怎么办?ES6为我们提供了得到参数的方法(xxx.length)。
1
2
3
4
|
function add(a,b) {
return a+b;
}
console.log(add.length); //2
|
两个坑:
(1)如果既使用默认值,又使用严谨模式的话,就会产生冲突。
1
2
3
4
5
|
function add(a,b=3) {
return a+b;
}
console.log(add(2));
|
(2)当参数中有默认值时,获取需要传递的参数个数时,不会计算有默认值的参数。所以这里需要注意的是add.length返回的参数个数是必须传递参数的个数。
1
2
3
4
|
function add(a,b=2) {
return a+b;
}
console.log(add.length); //1
|
这里说明一下,b的值不一定为2,也可以重新赋值
1
2
3
4
|
function add(a,b=2) {
return a+b;
}
console.log(add(2,4)); //6
|
箭头函数
如果箭头函数就一句,可以直接这么写
1
2
|
let add = (a,b=1)=> a+b;
console.log(add(2)); //3
|
否则需要加上花括号以及return
1
2
3
4
|
let add = (a,b=1)=> {
return a+b;
}
console.log(add(2)); //3
|
箭头函数中不可加new,也就是说箭头函数不能当构造函数进行使用。
9.ES6中的对象
对象赋值
之前对象赋值是这样的
1
2
3
4
|
let name = 'whittney';
let skill = 'web';
let obj = {name: name,skill:skill};
console.log(obj);
|
现在可以这样写
1
2
3
4
|
let name = 'whittney';
let skill = 'web';
let obj = {name,skill};
console.log(obj);
|
对象KEY值构建
1
2
3
4
5
|
let key = 'name';
let obj = {
[key]:'whittney'
};
console.log(obj);
|
OBJECT.IS( )方法进行对象比较
1
2
3
|
let obj1 = {name: 'whittney'};
let obj2 = {name: 'lily'};
console.log(Object.is(obj1.name,obj2.name)); //false
|
10.Symbol数据类型
1
2
|
let a = Symbol();
console.log(typeof a); //symbol
|
symbol数据类型和string数据类型的区别?
1
2
3
|
let a = Symbol('whittney');
console.log(a); //symbol数据类型,字体颜色为红色
console.log(a.toString()); //string数据类型,字体颜色为黑色
|
SYMBOL对象元素的保护作用
没有使用symbol之前
1
2
3
4
|
let obj = {name:'whittney',skill: 'web',age: 18};
for(let item in obj){
console.log(obj[item]); //输出 whittney web 18
}
|
假如这时有一个需求:不想打印出age
1
2
3
4
5
6
7
|
let obj = {name:'whittney',skill: 'web'};
let age = Symbol();
obj[age] = 18;
for(let item in obj){
console.log(obj[item]); //whittney web
}
console.log(obj); //{name:'whittney',skill: 'web',Symbol(): 18}
|
11.Set和WeakSet数据结构
SET数据结构(数组)
Set和Array 的区别是Set不允许内部有重复的值,如果有只显示一个,相当于去重。虽然Set很像数组,但是他不是数组。而且Set数据结构只能放数组。
1
2
|
let setData =new Set(['whittney','lily','lily','tina']);
console.log(setData); //Set(3) {"whittney", "lily", "tina"} 没有两个’lily‘,说明不能有相同的值
|
Set数据结构的增删查,没有改
(1)增:setData.add()
1
2
3
4
|
let setData =new Set(['whittney','lily','tina']);
console.log(setData); //Set(3) {"whittney", "lily", "tina"}
setData.add('jack');
console.log(setData); //Set(4) {"whittney", "lily", "tina", "jack"}
|
(2)删:setData.delete()
1
2
3
4
|
let setData =new Set(['whittney','lily','tina']);
console.log(setData); //Set(3) {"whittney", "lily", "tina"}
setData.delete('lily');
console.log(setData); //Set(2) {"whittney", "tina"}
|
(3)查:setData.has(),返回的是true或者false。
1
2
|
let setData =new Set(['whittney','lily','tina']);
console.log(setData.has('lily')); //true
|
(4)删除所有值:setData.clear();
1
2
3
|
let setData =new Set(['whittney','lily','tina']);
setData.clear();
console.log(setData); //Set(0) {}
|
(5)for…of…循环
1
2
3
4
|
let setData =new Set(['whittney','lily','tina']);
for(let item of setData){
console.log(item);
}
|
(6)forEach循环
1
2
3
4
|
let setData =new Set(['whittney','lily','tina']);
setData.forEach(function (item) {
console.log(item);
})
|
WEAKSET数据结构(对象)
WeakSet数据结构只能放数组。WeakSet里边的值也是不允许重复的。
1
2
3
4
|
let weakObj = new WeakSet();
let obj = { a:'abc',b:'efg'};
weakObj.add(obj);
console.log(weakObj);
|
坑:
1
|
如果你直接在new 的时候就放入值,将报错。
|
12.map数据结构
map的效率和灵活性更好。
(1)set():赋值
1
2
3
4
5
6
7
|
let json = {
name: 'whittney',
skill: 'web'
};
var map = new Map();
map.set(json,'js');
console.log(map);
|
(2)get():取值
1
2
3
4
5
6
7
8
9
10
|
let json = {
name: 'whittney',
skill: 'web'
};
var map = new Map();
map.set(json,'js'); //key:{name: "whittney", skill: "web"} value:"js"
map.set("iam",json);
console.log(map.get(json)); //'js'
console.log(map.get('iam')); //{name: "whittney", skill: "web"}
//由此可见,get获取的是map数据结构中的key值。
|
(3)delete():删除
1
2
3
4
5
6
7
8
|
let json = {
name: 'whittney',
skill: 'web'
};
var map = new Map();
map.set(json,'js'); //key:{name: "whittney", skill: "web"} value:"js"
map.delete(json);
console.log(map); //Map(0) {}
|
(4)map.has():查找是否有key为某某的map
1
2
3
4
5
6
7
8
|
let json = {
name: 'whittney',
skill: 'web'
};
var map = new Map();
map.set(json,'js'); //key:{name: "whittney", skill: "web"} value:"js"
console.log(map.has('js')); //false 查找key为'js'的map
console.log(map.has(json)); //true 查找key为json的map
|
(5)clear():清楚所有map
1
2
3
4
5
6
7
8
|
let json = {
name: 'whittney',
skill: 'web'
};
var map = new Map();
map.set(json,'js'); //key:{name: "whittney", skill: "web"} value:"js"
map.clear();
console.log(map);
|
13.用Proxy进行预处理
声明Proxy
1
2
3
4
5
|
let pro = new Proxy({
},{
// get set apply
})
|
第一个花括号就相当于我们方法的主体,后边的花括号就是Proxy代理处理区域,相当于我们写钩子函数的地方。
get属性
get属性是在你得到某对象属性值时预处理的方法,他接受三个参数:
target:得到的目标值
key:目标的key值,相当于对象的属性
property:这个不太清楚
1
2
3
4
5
6
7
8
9
10
11
12
13
|
let pro = new Proxy({
add: function (val) {
return val+100;
},
name: 'whittney'
},{
get: function (target,key,property) {
console.log(target); //{add: ƒ, name: "whittney"}
console.log(key); //name
return target[key]; //所以获取name,写法为target[key]
}
})
console.log(pro.name); //whittney
|
可以在控制台看到结果,先输出了target和key的值。相当于在方法调用前的钩子函数。
set属性
set属性是值你要改变Proxy属性值时,进行的预先处理。它接收四个参数。
target:目标值。
key:目标的Key值。
value:要改变的值。
receiver:改变前的原始值。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
let pro = new Proxy({
add: function (val) {
return val+100;
},
name: 'whittney'
},{
get: function (target,key,property) {
return target[key];
},
set: function (target,key,value,receiver) {
console.log(`setting ${key} = ${value}`); //setting name = lily
return target[key] = value;
}
})
console.log(pro.name); //whittney
pro.name='lily';
console.log(pro.name); //lily
//运行顺序是:
// whittney
// setting name = lily
// lily
|
apply属性
apply的作用是调用内部的方法,它使用在方法体是一个匿名函数。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
let target = function () {
return 'whittney';
};
var handler = {
apply(target, ctx, args) {
console.log('do apply');
return Reflect.apply(...arguments);
}
}
var pro = new Proxy(target, handler);
console.log(pro()); //do apply whittney
|
14.Promise
ES6中的promise很好的解决了回调地狱的问题。
什么是回调地狱?
回调地狱指的是多层嵌套回调时,写完的代码层次过多,很难进行维护和二次开发。
1
2
3
4
5
6
7
|
function fn1() {
function fn2() {
function fn3() {
...
}
}
}
|
PROMISE的基本用法
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
37
38
39
40
41
|
let state = 1;
function step1(resolve,reject) {
console.log("1.开始-做饭");
if(state == 1){
resolve("做饭--成功");
}else{
reject("做饭--错误");
}
}
function step2(resolve,reject) {
console.log("2.开始-吃饭");
if(state == 1){
resolve("吃饭--成功");
}else{
reject("吃饭--错误");
}
}
function step3(resolve,reject) {
console.log("3.开始-洗碗");
if(state == 1){
resolve("洗碗--成功");
}else{
reject("洗碗--错误");
}
}
new Promise(step1).then(function (val) {
console.log(val);
return new Promise(step2);
}).then(function (val) {
console.log(val);
return new Promise(step3);
}).then(function (val) {
console.log(val);
});
//1.开始-做饭
//做饭--成功
//2.开始-吃饭
//吃饭--成功
//3.开始-洗碗
//洗碗--成功
|
假如有中间有一个步骤失败,后面的步骤就不会进行下去。
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
|
let state = 1;
function step1(resolve,reject) {
console.log("1.开始-做饭");
if(state == 1){
resolve("做饭--成功");
}else{
reject("做饭--错误");
}
}
function step2(resolve,reject) {
console.log("2.开始-吃饭");
if(state == 1){
resolve("吃饭--成功");
}else{
reject("吃饭--错误");
}
}
function step3(resolve,reject) {
console.log("3.开始-洗碗");
let state = 2;
if(state == 1){
resolve("洗碗--成功");
}else{
reject("洗碗--错误");
}
}
new Promise(step1).then(function (val) {
console.log(val);
return new Promise(step2);
}).then(function (val) {
console.log(val);
return new Promise(step3);
}).then(function (val) {
console.log(val);
});
//1.开始-做饭
//做饭--成功
//2.开始-吃饭
//Uncaught (in promise) 吃饭--错误
|
15.类
类的使用
1
2
3
4
5
6
7
8
9
10
11
|
class Coder {
name(val){
return val; //这里没有返回值的话,后面使用name方法时会输出undefined
}
skill(val){
console.log(this); //this指的是Coder类
console.log(this.name('whittney')+':'+val);
}
}
let code = new Coder();
code.skill('web'); //whittney:web
|
注意:
1.两个方法中间不要写逗号;
2.这里的this指类本身;
3.注意return 的用法。
类的传参
用constructor( )进行传参,传递参数后可以直接使用this.xxx进行调用。
1
2
3
4
5
6
7
8
9
10
11
|
class Coder {
constructor(a,b){
this.a = a;
this.b = b;
}
add(){
return this.a + this.b;
}
}
let code = new Coder(2,3);
console.log(code.add()); //5
|
类的继承
声明一个htmler的新类并继承Coder类,htmler新类里边为空,这时候我们实例化新类,并调用里边的name方法。结果也是可以调用到的。注:使用extends继承。
1
2
3
4
5
6
7
8
9
10
|
class Coder{
name(val){
console.log(val);
}
}
class htmler extends Coder{
}
let code = new htmler;
code.name('whittney'); //whittney
|
16.模块化
模块化操作主要包括两个方面。
export :负责进行模块化,也是模块的输出。
import : 负责把模块引,也是模块的引入操作。
模块化基本使用
在src目录下新建一个temp.js文件,就是一个模块。里面代码如下,输出一个模块变量:
1
|
export var name = 'whittney';
|
在src目录的index.js文件中以import的形式引入:
1
2
|
import {name} from './temp';
console.log(name);
|
注意:
ES6的模块化不能直接在浏览器中预览,必须要使用Babel进行编译之后正常看到结果。
编译方法为:
一般我们的终端路径为项目名称下,如:project>
。但是执行以下命令时,需要进入project/src>
路径下
1
|
babel-node index.js
|
如何输出多个变量?
方法:把它们包装成对象就可以了。
temp.js文件
1
2
3
4
5
6
7
8
|
var a = 1;
var b = 2;
var c = 3;
export {a,b,c};
export function add(arg1,arg2){
return arg1+arg2;
}
//可以有多个export
|
index.js
1
2
3
4
5
|
import {a,b,c,add} from './temp';
console.log(a); //1
console.log(b); //2
console.log(c); //3
console.log(add(2,5)); //7
|
使用AS避免暴露模块里面的变量名称
给模块起一个更语义话的名称,输出和输入时直接使用该名称。比如:a as x
意思是给模块a另起一个名称x,避免模块a的名称暴露。
temp.js文件
1
2
3
4
5
6
7
8
|
var a = 1;
var b = 2;
var c = 3;
export {
a as x,
b as y,
c as z
}
|
index.js
1
2
3
4
|
import {x,y,z} from './temp';
console.log(x);
console.log(y);
console.log(z);
|
EXPORT DEFAULT的使用
temp.js文件
1
2
|
var a = 'whittney';
export default a;
|
index.js文件
1
2
|
import str from './temp';
console.log(str); //whittney
|
EXPORT和EXPORT DEFAULT的区别
export和export default最大的区别就是export不限变量数 可以一直写,而export default 只输出一次 而且 export出的变量想要使用必须使用{}来盛放,而export default 不需要 只要import任意一个名字来接收对象即可。
二、Array.includes()
在ES5,Array已经提供了indexOf用来查找某个元素的位置,如果不存在就返回-1,但是这个函数在判断数组是否包含某个元素时有两个小不足,第一个是它会返回-1和元素的位置来表示是否包含,在定位方面是没问题,就是不够语义化。另一个问题是不能判断是否有NaN的元素。
const arr1 = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', NaN] console.log('%s', arr1.indexOf(NaN))
结果:
-1
ES6提供了Array.includes()函数判断是否包含某一元素,除了不能定位外,解决了indexOf的上述的两个问题。它直接返回true或者false表示是否包含元素,对NaN一样能有效。
const arr1 = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', NaN] console.log('%s', arr1.includes('c')) console.log('%s', arr1.includes('z')) console.log('%s', arr1.includes(NaN))
结果:
true false true
includes()函数的第二个参数表示判断的起始位置。
const arr1 = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', NaN] console.log('%s', arr1.includes('d', 1)) console.log('%s', arr1.includes('d', 3)) console.log('%s', arr1.includes('d', 4))
结果:
true true false
第二个参数也可以是负数,表示从右数过来第几个,但是不改变判断搜索的方向,搜索方向还是从左到右。
console.log('%s', arr1.includes('k', -1)) console.log('%s', arr1.includes('k', -2)) console.log('%s', arr1.includes('i', -3))
结果:
false true false
转自《https://www.cnblogs.com/kongxianghai/p/7560343.html》