关于ES6中的一些常用知识点与使用示例整理

235 阅读6分钟

变量的解构赋值

数组

以前,为变量赋值,只能直接指定值:

 let a = 1;
 let b = 2;
 、、、、

但现在,es6允许我们写成这样:

 let [a,b] = [1,2];
 //a:1;
 //b:2;

上面的代码表示,在数组中,可以按照对应的位置,为变量进行赋值。不过需要注意一点的是:等号两边的模式需要相同。下面是一些例子

let [foo, [[bar], baz]] = [1, [[2], 3]];
foo // 1
bar // 2
baz // 3
let [ , , third] = ["foo", "bar", "baz"];
third // "baz"

若等号两边模式不同,结构不成功,变量的值为Undefined。

let [foo] = [];
let [bar, foo] = [1];
//以上两个赋值都不成功,foo的值都为undefined

对象

取值在我们编程中非常常见,比如从对象obj中取值。

const obj = { a:1, b:2, c:3};
、、、
const a = obj.a;
const b = obj.b;
const c = obj.c;

但是这样大家有没有发现,简单的取对象中的三个变量值,就需要三行代码实现。若使用结构赋值的话,我们只需要一行就可以解决;

const {a,b,c} = obj;
//a:1
//b:2
//c:3

对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。那么可能大家会考虑到一个问题,如果服务端返回的属性名不是我想要的,那么结果赋值不是也麻烦吗?不用担心,我们可以这样实现。如果服务端返回的属性名是a,而我们使用时需要用的属性名为b。那么我们就可以这样定义:

 const {a:b} = obj;
 //b:1

解构失败,变量的值也为undefined。

let {foo} = {a:1};
//foo:undefined

数据合并:主要对拓展运算符的使用

数组

之前合并两个数组,我们一般会用以下方法实现:

const a = [1,2,3]; 
const b = [1,5,6]; 
const c = a.concat(b);//[1,2,3,1,5,6]

若使用es6语法,我们可以这样实现:

const c = [...a,...b];//[1,2,3,4,5,6]

不过需要注意的是,这两种方法实现的都只是浅拷贝,使用的时候需要注意。

对象

关于对象的合并,我们之前常用的方法是:

const obj1 = { a:1}; 
const obj1 = { b:1};
const obj = Object.assgin({}, obj1, obj2);//{a:1,b:1}

若使用es6语法,我们可以这样实现:

const obj = {...obj1,...obj2};
//obj:{a:1,b:2}

模板字符串

这边我们举一个例子。

const name = 'ac'; 
const score = 79; 
let result = ''; 
let desc = '的考试成绩'
if(score > 60){ 
  result = `${name}${desc}及格`; 
}else{ 
  result = `${name}${desc}不及格`; 
}

是不是看起来就觉得很麻烦。我们再来看一个例子。

const name = 'ac';
const score = 100;
const result = `${name}${score > 60?${desc}'合格':${desc}'不合格'}`;

这样看起来是不是方便多了。 es6中增加了对模板字符串的使用。在{}内可以放入任意的 JavaScript 表达式,可以进行运算,以及引用对象属性。

数组常用的扩展方法

includes

该方法返回一个布尔值,表示某个数组是否包含给定的值。

[1,2,3].includes(1);//true
[1,2,3].includes(4);//false

该方法的第二个参数表示搜索的起始位置,默认为0。如果第二个参数为负数,则表示倒数的位置,如果这时它大于数组长度(比如第二个参数为-4,但数组长度为3),则会重置为从0开始。

[1,2,3].includes(3,3);//false
[1, 2, 3].includes(3, -1); // true

利用该方法可以优化if判断语句。我们常常一个判断语句中需要判断多个值,我们可能会这样去判断:

if( 
    type == 1 || 
    type == 2 || 
    type == 3 || 
    type == 4 
   ){ 
        //... 
    }

这样是不是看起来特别麻烦,如果用了includes方法,我们可以优化为:

let condition = [1,2,3,4];
if(condition.includes(type)){}

find()

数组实例的find方法,用于找出第一个符合条件的数组成员。它的参数是一个回调函数,所有数组成员依次执行该回调函数,直到找出第一个返回值为true的成员,然后返回该成员。如果没有符合条件的成员,则返回undefined

const demo = [1,2,3,4,5];
demo.find((n) => n > 4);//5

关于find方法在项目中的运用。 在项目中,一些没分页的列表的搜索功能由前端来实现,搜索一般分为精确搜索和模糊搜索。搜索也要叫过滤,一般我们可以用filter来实现。

const a = [1,2,3,4,5];
const result = a.filter( item =>{ return item === 3 } )

考虑到性能优化问题,我们一般选用find方法,一旦找到符合条件的数据时,便不会继续便利数组。

const a = [1,2,3,4,5]; 
const result = a.find( item =>{ return item === 3 } )

flat()

我们先看一个例子: 一个部门JSON数据中,属性名是部门id,属性值是个部门成员id数组集合,现在要把有部门的成员id都提取到一个数组集合中。是不是还在考虑通过遍历最后再去重去实现吗?

const deps = {
'事业部':[1,2,3], 
'人事部':[4,8,12], 
'财务部':[9,14,79]} 
let member = []; 
for (let item in deps){ 
  const value = deps[item]; 
  if(Array.isArray(value)){ 
    member = [...member,...value] } 
  } 
//member:[1,2,3,4,8,12,9,14,79]

但如果我们用flat方法去实现,会发现方便很多;

const deps = {
'事业部':[1,2,3], 
'人事部':[4,8,12]
} 
const menber = Object.values(deps).flat();//[1,2,3,4,8,12]

数组的成员有时是数组,flat()方法用于将嵌套的数组“拉平”,变成一维的数组。该方法返回一个新数组,对原数据没有影响。默认flat()方法只会拉平一层,若想要拉平多层,可以传入一个指定参数。如flat(2);

let demo = [1,[[2,3],4];
demo.flat(2);//[1,2,3,4]

如果不管有多少层嵌套,都要转成一维数组,可以用Infinity关键字作为参数。

[1, [2, [3]]].flat(Infinity)
// [1, 2, 3]

获取对象属性值

我们要获取一个对象属性值,首先需要去判断这个对象是否存在,然后再去取。

const name = obj && obj.name;

如果嵌套层级太多的话,相应的判断条件就会很多,使用起来查阅起来都不方便。我们可以使用es6中的可选链操作符去获取。

const name = obj?.name

对象的属性名表达式

定义对象属性有两种方法:

const obj = {
  foo:true,
  name:'ac'
}
obj.age = 25;//1
obj['a' + 'b'] = '123';//2

若属性名是动态变化的,第一种方法显然无法实现。对象的属性名表示式就很好的为我们解决了这个问题。

let obj = {};
let index = 1; 
obj[`topic${index}`] = '这是内容';

空值合并运算符

我们在处理输入框相关业务时,往往会判断输入框未输入值的场景。

if(value !== null && value !== undefined && value !== ''){ //... }

使用空值合并运算符,会大大减少判断条件的书写

if(value ?? '' !== ''){
...
}

??:当左侧的操作数为 [null] 或者 [undefined] 时,返回其右侧操作数,否则返回左侧操作数。

异步函数

异步函数很常见,一般用promise实现

const fn1 = () =>{ 
return new Promise((resolve, reject) => { 
  setTimeout(() => { resolve(1); }, 300); }); 
} 
const fn2 = () =>{ 
return new Promise((resolve, reject) => { 
  setTimeout(() => { resolve(2); }, 600); }); } 
const fn = () =>{ 
  fn1().then(res1 =>{ 
  console.log(res1);// 1 
  fn2().then(res2 =>{ 
  console.log(res2);//2
  }) 
 }) 
}

如果这样调用异步函数,视觉上看也很吃力。 改进:

const fn = async () =>{ 
 const res1 = await fn1(); 
 const res2 = await fn2(); 
 console.log(res1);// 1 
 console.log(res2);// 2 
}