Js

64 阅读4分钟
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.数组常用的方法
//数组排序
//sort() 方法用原地算法对数组的元素进行排序,并返回数组
	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) //降序

//数组去重
//indexOf()方法返回在数组中可以找到一个给定元素的第一个索引,如果不存在,则返回-1。
	 // 1.创建一个新数组 把老数组里面的值 拷贝到新数组里
     // 2.前提条件 新数组里没有这一项

 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)

//set容器,new Set(数组)得到的是一个set对象,通过扩展运算符[...new Set(arr)]得到一个新数组
 let arr = [1, 2, 3, 3, 4, 4, 5]
 let array = [...new Set(arr)]
 
 
//filter去重  方法一行解决
 const arr = [1,2,3,4,1,3]
 const result = arr.filter((item,index,array) => index === array.indexOf(item))
 
//reduce去重
 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,undefinedNAN
    - 设置为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) // 取最大系数  10的多少次幂 10**len
                  }