JavaScript相关面试题5:ES7-ES12

简介: 使用场景loading关闭需要每次发送请求,都会有loading提示,请求发送完毕,就需要关闭loading提示框,不然界面就无法被点击。不管请求成功或是失败,这个loading都需要关闭掉,这时把关闭loading的代码写在finally里再合适不过了

文章目录

说说你的ES7-ES12的了解

ES2016(ES7)

ES2017(ES8)

ES2018(ES9)

说说你的ES7-ES12的了解

ES2016(ES7)

Array.prototype.includes()

includes() 方法用来判断一个数组是否包含一个指定的值,如果包含则返回 true,否则返回 false。


语法

arr.includes(valueToFind[, fromIndex])

valueToFind,需要查找的元素值。

fromIndex 可选 从fromIndex 索引处开始查找 valueToFind。如果为负值(即从末尾开始往前跳 fromIndex 的绝对值个索引,然后往后搜寻)。默认为 0。


使用 includes()只能判断简单类型的数据,对于复杂类型的数据,比如对象类型的数组,二维数组,这些是无法判断的.

如果只想知道某个值是否在数组中存在,而并不关心它的索引位置,建议使用includes(),如果想获取一个值在数组中的位置,那么使用indexOf方法。


幂运算符

console.log(2 ** 10); // 1024

幂运算符的两个*号之间不能出现空格,否则语法会报错。


ES2017(ES8)

Object.values()

Object.values 方法返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键值。


const obj = {

 name: "jimmy",

 age: 18,

 height: 188,

};

console.log(Object.values(obj));

// [ 'jimmy', 18, 188 ]

1

2

3

4

5

6

7

Object.entries()

Object.entries() 方法返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历属性的键值对数组。


const obj = {

 name: "jimmy",

 age: 18,

 height: 188,

};

console.log(Object.entries(obj));

// [ [ 'name', 'jimmy' ], [ 'age', 18 ], [ 'height', 188 ] ]

console.log(Object.entries([1, 2, 3]));

// [ [ '0', 1 ], [ '1', 2 ], [ '2', 3 ] ]

1

2

3

4

5

6

7

8

9

Object.getOwnPropertyDescriptors()

Object.getOwnPropertyDescriptors() 方法用来获取一个对象的所有自身属性的描述符。


const obj = {

 name: "jimmy",

 age: 18,

};

const desc = Object.getOwnPropertyDescriptors(obj);

console.log(desc);  

// 打印结果

{

 name: {

   value: 'jimmy',

   writable: true,

   enumerable: true,

   configurable: true

 },

 age: {

  value: 18,

  writable: true,

  enumerable: true,

  configurable: true

 }

}


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

●value表示当前对象的默认值

●writable表示对象属性是否可以修改

●enumerable表示当前这个属性是否可以出现在对象的枚举属性中

●configurable表示当前对象的属性能否用delete删除


设置 writable: false和configurable: false,为false时,对象的name对象的值不能改变和不能被删除,打印出来还是原来的对象。


String.prototype.padStart

把指定字符串填充到字符串头部,返回新字符串。

语法

str.padStart(targetLength [, padString])


targetLength

当前字符串需要填充到的目标长度。如果这个数值小于当前字符串的长度,则返回当前字符串本身。

padString 可选

填充字符串。如果字符串太长,使填充后的字符串长度超过了目标长度,则只保留最左侧的部分,其他部分会被截断。此参数的默认值为 " "


应用场景

日期格式化:yyyy-mm-dd的格式:


const now = new Date()

const year = now.getFullYear()

// 月份和日期 如果是一位前面给它填充一个0

const month = (now.getMonth() + 1).toString().padStart(2, '0')

const day = (now.getDate()).toString().padStart(2, '0')

console.log(year, month, day)

console.log( `${year}-${month}-${day}` )

//输入今天的日期

1

2

3

4

5

6

7

8

数字替换(手机号,银行卡号等)


const tel = '18781268679'

const newTel = tel.slice(-4).padStart(tel.length, '*')

console.log(newTel) // *******5678

1

2

3

String.prototype.padEnd

把指定字符串填充到字符串尾部,返回新字符串。


应用场景

在JS前端我们处理时间戳的时候单位是ms毫秒,但是,后端同学返回的时间戳则不一样是毫秒,可能只有10位,以s秒为单位。所以,我们在前端处理这个时间戳的时候,保险起见,要先做一个13位的补全,保证单位是毫秒


尾逗号 Trailing commas

ES8 允许函数的最后一个参数有尾逗号(Trailing comma)。 此前,函数定义和调用时,都不允许最后一个参数后面出现逗号。


async/await

使用 Promise 能很好地解决回调地狱的问题,但如果处理流程比较复杂的话,那么整段代码将充斥着 then,语义化不明显,代码不能很好地表示执行流程

async/await是比 Promise 更优雅的异步方式

前面添加了async的函数在执行后都会自动返回一个Promise对象:


function foo() {

   return 'jimmy'

}

console.log(foo()) // 'jimmy'

1

2

3

4

添加async后


async function foo() {

   return 'jimmy' // Promise.resolve('jimmy')

}

console.log(foo()) // Promise

foo()

1

2

3

4

5

async函数中使用await,那么await这里的代码就会变成同步的了,意思就是说只有等await后面的Promise执行完成得到结果才会继续下去,await就是等待。


function timeout() {

   return new Promise(resolve => {

       setTimeout(() => {

           console.log(1)

           resolve()

       }, 1000)

   })

}


// 不加async和await是2、1   加了是1、2

async function foo() {

   await timeout()

   console.log(2)

}

foo()

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

使用场景

假如有这样一个使用场景:需要先请求 a 链接,等返回信息之后,再请求 b 链接的另外一个资源。下面代码展示的是使用 fetch 来实现这样的需求,fetch 被定义在 window 对象中,它返回的是一个 Promise 对象


fetch('https://blog.csdn.net/')

 .then(response => {

   console.log(response)

   return fetch('https://juejin.im/')

 })

 .then(response => {

   console.log(response)

 })

 .catch(error => {

   console.log(error)

 })

1

2

3

4

5

6

7

8

9

10

11

虽然上述代码可以实现这个需求,但语义化不明显,代码不能很好地表示执行流程。基于这个原因,ES8 引入了 async/await,这是 JavaScript 异步编程的一个重大改进,提供了在不阻塞主线程的情况下使用同步代码实现异步访问资源的能力,并且使得代码逻辑更加清晰。

通过上面代码,你会发现整个异步处理的逻辑都是使用同步代码的方式来实现的,而且还支持 try catch 来捕获异常,这感觉就在写同步代码,所以是非常符合人的线性思维的。


注意点

●await 只能在 async 标记的函数内部使用,单独使用会触发 Syntax error。

●await后面需要跟异步操作,不然就没有意义,而且await后面的Promise对象不必写then,因为await的作用之一就是获取后面Promise对象成功状态传递出来的参数。


async/await的缺陷

Async/await 让你的代码看起来是同步的,在某种程度上,也使得它的行为更加地同步。 await 关键字会阻塞其后的代码,直到promise完成,就像执行同步操作一样。它确实可以允许其他任务在此期间继续运行,但您自己的代码被阻塞

这意味着您的代码可能会因为大量await的promises相继发生而变慢。每个await都会等待前一个完成,而你实际想要的是所有的这些promises同时开始处理(就像我们没有使用async/await时那样)。


ES2018(ES9)

Object Rest & Spread

在 ES9 新增 Object 的 Rest & Spread 方法


const input = {

 a: 1,

 b: 2,

 c: 3,

}


const output = {

 ...input,

 c: 4

}


console.log(output)

// {a: 1, b: 2, c: 4}

1

2

3

4

5

6

7

8

9

10

11

12

13

这块代码展示了 spread 语法,可以把 input 对象的数据都拓展到 output 对象,这个功能很实用。需要注意的是,如果存在相同的属性名,只有最后一个会生效

注意点


const obj = { x: { y: 10 } };

const copy1 = { ...obj };

const copy2 = { ...obj };

obj.x.y = "jimmy";

console.log(copy1, copy2);

// x: {y: "jimmy"} x: {y: "jimmy"}

console.log(copy1.x === copy2.x);

// → true

1

2

3

4

5

6

7

8

如果属性的值是一个对象的话,该对象的引用会被拷贝,而不是生成一个新的对象。


const input = {

 a: 1,

 b: 2,

 c: 3

}


let { a, ...rest } = input


console.log(a, rest) // 1 {b: 2, c: 3}

1

2

3

4

5

6

7

8

9

当对象 key-value 不确定的时候,把必选的 key 赋值给变量,用一个变量收敛其他可选的 key 数据,这在之前是做不到的。注意,rest 属性必须始终出现在对象的末尾,否则将抛出错误


for await of

异步迭代器(for-await-of):循环等待每个Promise对象变为resolved状态才进入下一步。

ES9 中可以用 for…await…of 的语法来操作


function TimeOut(time) {

   return new Promise(function(resolve, reject) {

       setTimeout(function() {

           resolve(time)

       }, time)

   })

}


async function test() {

   let arr = [TimeOut(2000), TimeOut(1000), TimeOut(3000)]

   for await (let item of arr) {

       console.log(Date.now(), item)

   }

}

test()

// 1560092345730 2000

// 1560092345730 1000

// 1560092346336 3000


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

for await of 环等待每个Promise对象变为resolved状态才进入下一步。所有打印的结果为 2000,1000,3000


Promise.prototype.finally()

Promise.prototype.finally() 方法返回一个Promise,在promise执行结束时,无论结果是fulfilled或者是rejected,在执行then()和catch()后,都会执行finally指定的回调函数。这为指定执行完promise后,无论结果是fulfilled还是rejected都需要执行的代码提供了一种方式,避免同样的语句需要在then()和catch()中各写一次的情况。


使用场景

loading关闭

需要每次发送请求,都会有loading提示,请求发送完毕,就需要关闭loading提示框,不然界面就无法被点击。不管请求成功或是失败,这个loading都需要关闭掉,这时把关闭loading的代码写在finally里再合适不过了


目录
相关文章
|
1月前
|
JSON JavaScript 前端开发
Javascript基础 86个面试题汇总 (附答案)
该文章汇总了JavaScript的基础面试题及其答案,涵盖了JavaScript的核心概念、特性以及常见的面试问题。
40 3
|
1月前
|
前端开发 JavaScript
JavaScript 面试系列:如何理解 ES6 中 Generator ?常用使用场景有哪些?
JavaScript 面试系列:如何理解 ES6 中 Generator ?常用使用场景有哪些?
|
2月前
|
JavaScript 前端开发
常见的JS面试题
【8月更文挑战第5天】 常见的JS面试题
57 3
|
5天前
|
Web App开发 JavaScript 前端开发
前端Node.js面试题
前端Node.js面试题
|
2月前
|
存储 JavaScript 前端开发
2022年前端js面试题
2022年前端js面试题
35 0
|
2月前
|
JavaScript 前端开发 程序员
JS小白请看!一招让你的面试成功率大大提高——规范代码
JS小白请看!一招让你的面试成功率大大提高——规范代码
|
2月前
|
存储 JavaScript 前端开发
JS浅拷贝及面试时手写源码
JS浅拷贝及面试时手写源码
|
2月前
|
JavaScript 前端开发
JS:类型转换(四)从底层逻辑让你搞懂经典面试问题 [ ] == ![ ] ?
JS:类型转换(四)从底层逻辑让你搞懂经典面试问题 [ ] == ![ ] ?
|
3月前
|
缓存 JavaScript 前端开发
js高频面试题,整理好咯
中级前端面试题,不低于12k,整理的是js较高频知识点,可能不够完善,大家有兴趣可以留言补充,我会逐步完善,若发现哪里有错,还请多多斧正。
|
3月前
|
JavaScript
JS【详解】setTimeout 延时(含清除 setTimeout,计时开始时间,0 秒延时解析,多 setTimeout 执行顺序,setTimeout 应用场景,网红面试题)
JS【详解】setTimeout 延时(含清除 setTimeout,计时开始时间,0 秒延时解析,多 setTimeout 执行顺序,setTimeout 应用场景,网红面试题)
671 0