1. 事件循环的机制了解吗?宏任务和微任务的执行顺序是怎样的?
- JS是从上到下依次执行,是单线程的,当出现异步任务时会放在任务队列,等同步任务执行完后,再执行异步队列,整个流程就是事件循环机制
- 宏任务:setTimeOut setInterval
- 微任务:promise.then async await
2. 用过promise吗?它的使用是为了解决一个什么问题?promise底层是怎么设计的?
1. Promise对象只有三种状态。
异步操作“未完成”(pending)
异步操作“已完成”(resolved,又称fulfilled)
异步操作“失败”(rejected)
异步操作成功,Promise对象传回一个值,状态变为resolved。
异步操作失败,Promise对象抛出一个错误,状态变为rejected。
2.promise的回调是同步的,then是异步的
3.可以链式调用
4.原型上的方法:
- .then返回一个Promise对象,可以接着调用.then
- .catch发生错误时的回调函数 也返回一个promise对象
- .finally无论结果如何都会调用
5.自身的API
- Promise.resolve()状态为已完成调用
- Promise.reject()状态为失败调用
- Promise.race()赛跑机制
- Promise.all()等待机制
3.数组常用的方法
let arr = [10,20,8,3,90,6,55]
arr.sort(function(a,b){
return a - b
})
console.log(arr)
arr.sort(function(a,b){
return b - a
})
console.log(arr)
let arr = ['a', 'b', 'c', 'a', 'a', 'e', 'd', 'd']
let newArr = []
arr.forEach((item, index) => {
if (newArr.indexOf(arr[index]) === -1) {
newArr.push(arr[index])
}
})
console.log(newArr)
let arr = [1, 2, 3, 3, 4, 4, 5]
let array = [...new Set(arr)]
const arr = [1,2,3,4,1,3]
const result = arr.filter((item,index,array) => index === array.indexOf(item))
array.reduce((unique,item)=>unique.includes(item) ? unique : [...unique,item] ,[])
4.检测数据类型的方法
typeof
instanceof
constructor
5.深拷贝 浅拷贝
浅拷贝: 拷贝对象最外层,如果对象里面还有对象,使用的是同一个地址,修改两者之间有影响
深拷贝: 拷贝对象的所有
方法: 浅拷贝 =》 object.assign() 展开运算符…
深拷贝 =》 JSON.parse(JSON.stringiFy(obj)) (但是如果里面有 function 和 undefined 不可用) lodash里的_.cloneDeep(obj)
自己封装实现: 通过for in遍历对象,把对象里的每一项复制,深拷贝多一步判断是否是object,如果是递归重新调用这个方法
newObj[k] = obj[k]
newObj[k] = typeof obj[k] == 'object' ? getObj(obj[k]) : obj[k]
6.数据类型有哪些?
基本数据类型: number string boolean null undefined NaN Symbol(ES6新增:独一无二的值)
复杂数据类型: Object Array Function
大数类型: BigInt类型
+ 出现的场景: 当服务端返回一个大数,需要拿到大数进行运算后,再传递给服务端
+ 解决: 会有数据丢失的问题: 变成BigInt然后按照BigInt运算,再转为字符串
7.null和undefined的区别?
相同点: 在if判断里都是false
区别:
- null转化为数字类型是0,undefined是NAN
- 设置为null的变量或者对象会被内存收集器回收
- undefined是代表调用一个值而该值却没有赋值,这时候默认则为undefined
- null是一个很特殊的对象,最为常见的一个用法就是作为参数传入(说明该参数不是对象)
8. 0.1 + 0.2 为什么不等于0.3 ?
js中有浮点数的计算,会出现精度丢失的问题「js都是已二进制在计算机存储的,浮点数转换为二进制kennel出现无限循环,最多存储64位舍弃了一些值,值本身就出现了精度丢失的问题」
解决方案:
1. toFixed保留N位小数,自己四舍五入
2. 扩大系数法「自己封装」
3. 第三方库「Math.js decimal.js big.js」
核心思想:首先转换为数字型, 获取数值的最大系数, 然后乘以最大系数 相加或相减后 再除以最大系数
const plus = function plus (num1, num2){
num1 = +num1
num2 = +num2
if(isNaN(num1) || isNaN(num2)) return NaN
const max = Math.max(coefficient(num1),coefficient(num2))
const plus = (num1 * max + num2 * max) / max
return plus
}
const coefficient = function coefficient(num) {
num = num + ''
let [, char = ''] = num.split('.')
const len = char.length
return Math.pow(10,len)
}