「2024」打算跳槽涨薪,必问面试题及答案 -- ECMAScript 篇

Promises/A+ 规范是 JavaScript Promise 的标准,规定了一个Promise 所必须具有的特性。

Promise 是一个构造函数,接收一个函数作为参数,返回一个Promise 实例。一个 Promise实例有三种状态,分别是 pending、resolved 和 rejected,分别代表了进行中、已成功和已失败。实例的状态只能由 pending 转变 resolved 或者 rejected 状态,并且状态一经改变,就凝固了,无法再被改变了。状态的改变是通过 resolve() 和 reject() 函数来实现的,我们可以在异步操作结束后调用这两个函数改变 Promise 实例的状态,它的原型上定义了一个 then 方法,使用这个 then 方法可以为两个状态的改变注册回调函数。这个回调函数属于微任务,会在本轮事件循环的末尾执行。

相关面试题

const promise = new Promise((resolve, reject) => {

console.log(1);

resolve();

console.log(2);

})

promise.then(() => {

console.log(3);

})

console.log(4);

/* 运行结果

1 2 4 3

*/

6、ES6 中的 await 和 then 的区别?


Async / Await ,其中 await 关键字存在async函数表达式中,用于等待 Promise 对象,暂停执行,等到异步操作完成后,恢复 async 函数的执行并返回解析值。如果把 await 放在 asnyc 函数体外,会报语法错误。

new Promise().then(),其中 then 是原型上的一个方法,接收两个参数,第一个参数是Promise执行成功时的回调,第二个参数是Promise执行失败的回调,两个函数只会有一个被调用。

它两之间的区别:

  • await 会暂停所在 async 函数的执行,而 Promise 的 then 会继续执行当前函数,对于堆栈来说,这个不同点非常关键。

  • await 返回的直接是数据,而 then 返回的是方法,方法里面带有数据。

  • async / await 基于 promise 实现的。

7、Symbol 类型的注意点。


Symbol 是一个新的原始数据类型,表示独一无二的值,它是 js 的第七种数据类型,类似于字符串的数据类型。

使用 Symbol 的注意点有:

  • Symbol 函数前不能使用 new 命令,否则会报错。

  • Symbol 函数可以接受一个字符串作为参数,表示对 Symbol 实例的描述,主要是为了在控制台显示,或者转为字符串时,比较容易区分。

  • Symbol 作为属性名,该属性不会出现在 for…in、for…of 循环中,也不会被 Object.keys()、Object.getOwnPropertyNames()、JSON.stringify() 返回。

  • Object.getOwnPropertySymbols 方法找到对象的所有属性名的 Symbol 值,作为数组返回。

  • Symbol.keyFor 方法返回一个已登记的 Symbol 类型值的 key 。

8、Set 和 weakSet 结构


ES6 提供了新的数据结构 Set,它类似于数组,但是成员的值都是唯一的,会通过 Object.is 方法自动去重。

WeakSet 结构与 Set 结构类似,也是不重复的集合。但是 WeakSet 的成员只能是对象,不能是其他类型的值,WeakSet 中的对象都是弱引用,因此能够被垃圾回收自动清理。

9、Object.assign 和扩展运算法是深拷贝还是浅拷贝,两个区别?


Object.assign 使用:

let outObj = {

a:1,

b:2

}

let newObj = Object.assign({},outObj)

newObj.a = 3;

console.log(newObj) //{a: 3, b: 2}

扩展运算符:

let outObj = {

a:1,

b:2

}

let newObj = { …outObj }

newObj.a = 3;

console.log(newObj) //{a: 3, b: 2}

Object.assign 和 扩展运算 都是浅拷贝。

Object.assign 方法接收的第一个参数作为目标对象,后面的对象作为源对象,然后把所有源对象合并到目标对象中,它会修改目标对象,因此会触发 setter 。

扩展运算符 … 使用时,数组或对象中的每一个值都会被拷贝到一个新的数组或对象中,它不复制继承的属性或类的属性,但它会复制 ES6 的 Symbols 属性。

10、如何实现 0.1+0.2 == 0.3 结果返回真?


为什么 0.1+0.2 != 0.3 ?

JS 中采用的 IEEE754 的双精度标准,计算机内部存储数据的编码时,0.1 在计算机内部根本不是精确的 0.1,而是有舍入误差的。

console.log(0.1+0.2) // 0.30000000000000004

正是有舍入,所以我们发现 0.1+0.2 并不等于0.3。

如何解决?

Number.EPSILON 是 javaScript 表示的最小精度,这个值就相当于 2 的 -52 次方。

console.log( Number.EPSILON ) // 2.220446049250313e-16

console.log( Number.EPSILON === Math.pow(2, -52) ) //true

引入 Number.EPSILON 目的在于:浮点计算时,设置一个误差范围,如果小于这个值就忽略不计。所以:

function isEqual( a, b ){

if( a-b < Number.EPSILON ){

return true

}else{

return false

}

}

console.log( isEqual( 0.1+0.2, 0.3 ) )

11、ECMAScript 6 怎么写 class ,为何会出现 class?


ES6 中新增 class ,它是为了补充 js 中缺少的一些面向对象语言的特性,本质上来说它只是一种语法糖,它的绝大多数功能 ES5 都可以实现,新的 class 写法让对象原型写法更清晰。添加 class 之后,有利于我们更好的组织代码,在 class 中添加方法,其实就是添加到类的原型上。

class 应用:

class Phone{

// 构造函数

constructor( brand, price ){

this.brand = brand;

this.price = price

},

call(){

console.log(“可以打电话”)

}

}

// 实例化对象

let hw = new Phone( ‘华为’, 999 )

12、setTimeout、Promise、Async/Await 的区别


setTimeout 是异步执行函数,js 主线程运行到此函数时,不会等待 setTimeout 中的回调函数,回调函数会被压进消息队列,然后直接向下执行,当执行完当前事件循环的时候,回调函数会在下次事件循环中被执行。

console.log(1)

setTimeout(()=>{

console.log(2)

},0)

console.log(3)

// 运行结果:1 3 2

Promise 本身是同步的立即执行函数,当在执行体中执行 resolve 或 reject 的时候,此时是异步操作,会先执行 then / catch 等,等主栈完成后,才会执行 resolve reject 中的方法。

console.log(1)

var p =new Promise(( resolve, reject )=>{

console.log(2)

resolve(3)

})

p.then((res)=>{

console.log(res)

})

console.log(4)

// 运行结果:1 2 4 3

Async/Await 函数返回的是一个 Promise 对象,当函数执行的时候,一旦遇到 await 就会先返回,等到触发的异步操作完成,在执行函数体后面的语句。

await的含义为等待,也就是 async 函数需要等待await后的函数执行完成并且有了返回结果(Promise对象)之后,才能继续执行下面的代码。await通过返回一个Promise对象来实现同步的效果。

async function a1(){

console.log( 1 );

await a2();

console.log( 2 )

}

async function a2(){

console.log( 3 )

}

console.log( 4 );

a1();

console.log( 5 )

// 运行结果 4 1 3 5 2

13、forEach、for in、for of 三者区别


forEach 是数组的方法,进行遍历数组的。

for…in 不仅可以遍历数组,还可以对象。

for…of 进行遍历数组的。

for…in 与 for… of 遍历对象时,in 使用的是下标,而 of 使用的是 key。

14、说一下 es 6 的导入导出模块


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

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

export 对外暴露数据方式有三种:

方式1:分别暴露

export let person = “前端小姐姐”

export function showName(){

console.log( “倩倩” )

}

方式2:统一暴露

let person = “前端小姐姐”

function showName(){

console.log( “倩倩” )

}

export {

person,

showName

}

方式3:默认暴露

export default{

person = “前端小姐姐”,

showName: function(){

console.log( “倩倩” )

}

}

import 引入方式有三种:

方式1:通用的导入方式

import * as m from “./src/js/m.js”

console.log( “m”,m )

方式2:解构赋值

import { person, showName } from “./src/js/m.js”

// 重名时,可自定义名字

import { person as per, showName } from “./src/js/m.js”

// 针对默认暴露也可以这么写

import { default as m } from “./src/js/m.js”

方式3:简便形式,针对默认暴露

import m from “./src/js/m.js”

15、介绍下 Set、Map的区别 ?


应用场景 Set 用于数组重组,Map 用于数据储存。

对于Set:

  • 成员不能重复。

  • 只有键值没有键名,类似数组。

  • 可以使用 for…of 遍历

  • 方法有 size、add、delete、has、clear

对于Map:

  • 键值对的集合,类似集合。

  • 可以 for…of 遍历

  • 方法有 size、set、delete、has、clear


光说理论是不是都要困了,现在是时候大展拳脚了!看看你对 ES 知识掌握到底怎么样?


16、写出下面代码运行结果。


new Promise((resolve)=>{

console.log( 1 )

resolve()

}).then(()=>{

console.log( 2 )

new Promise(res=>{

res(1)

}).then(()=>{

console.log( 3 )

new Promise(res=>{

res(1)

}).then(()=>{

console.log( 4 )

})

}).then(()=>{

new Promise(res=>{

res(1)

}).then(()=>{

console.log( 5 )

})

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。

因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
onsole.log( 5 )

})

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。

因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

[外链图片转存中…(img-303cLyci-1715743535514)]

[外链图片转存中…(img-wesYOw9l-1715743535515)]

[外链图片转存中…(img-8FcgU3Bz-1715743535515)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值