前端面试题(持续更新)

108 阅读2分钟

1. 如何让下面的判断成立

if(a == 1 && a == 2 && a == 3){
    console.log('等式成立了');
}

比较规则

  1. 两端存在 NaN, 返回false
  2. undefined 和 null 只有和自身比较时, 才会返回 true, 和其他原始类型比较返回 fasle
  3. 两端同类型, 比较值
  4. 两端都是原始类型, 转换成数字重新比较
  5. 一端是原始类型, 一端是对象类型, 把对象转成原始类型重新比较
对象如何转原始类型
1. 如果对象拥有(Symbol, toPrimitive) 方法, 调用该方法
    若该方法能得到原始值, 使用该原始值
    若得不到原始值, 抛出异常
2. 调用对象的 valueOf 方法
    若该方法能得到原始值, 使用该原始值
    若得不到原始值, 进入下一步
3. 调用对象的 toString 方法
    若该方法得到原始值, 使用该原始值
    若得不到原始值, 抛出异常

解题思路

只能用对象做文章, 让返回的值递增

const a = {
    n: 1,
    [Symbol.toPrimitive](){
        console.log('symbol toPrimitive 被调用了');
        return this.n++;
    },
    valueOf(){
        console.log('valueOf 被调用了');
        return this.n++;
    },
    toString(){
        console.log('toString 被调用了');
        return this.n++;
    }
}

2. 如何理解JS异步?

JS 是一门单线程的语言, 这是因为它运行在浏览器的渲染主线程中, 而渲染主线程只有一个

而渲染主线程承担着诸多的工作, 渲染页面、执行 JS 都在其中运行

如果使用同步的方式, 就极有可能导致主线程产生阻塞, 从而导致消息队列中的很多其他任务无法得到执行

这样一来, 一方面会导致繁忙的主线程白白消耗时间, 另一方面, 导致页面无法及时更新, 给用户造成卡死现象

所以浏览器采用异步方式来避免, 具体做法是当某些任务发生时, 比如计时器、网络、事件监听,

主线程将任务交给其他线程去处理, 自身立即结束任务的执行, 转而执行后续代码, 当其他线程完成时,

将事件先传递的回调函数包装成任务,加入消息队列的末尾排队, 等待主线程调度执行

在这中异步模式下,浏览器永不阻塞,从而最大限度的保证了单线程的流畅运行

3. 数组去重

  1. Set + 扩展运算符
[...new Set(arr)]
  1. filter + indexOf
arr.filter((item,index) =>{
    return arr.indexOf(item) === index;
})
  1. reduce方法
arr.reduce((acc,item)=>{
    acc.includes(item)? acc : [...acc,item]
},[])
  1. Map数据结构
const map = new Mpa();
arr.filter(item =>{
    !map.has(item) && map.set(item,1)
})