2022 年初面试题汇总 (更新中...)

125 阅读6分钟
  1. 1 + 2 + '3' + 4 // '334'
  2. 0 == null
/** 
使用 == 比较中的5条规则:
1. `NaN`和其他任何类型比较永远返回`false`(包括和他自己)
2. Boolean 和其他任何类型比较,Boolean 首先被转换为 Number 类型
3. `String`和`Number`比较,先将`String`转换为`Number`类型
4. `null == undefined`比较结果是`true`,除此之外,`null`、`undefined`和其他任何结果的比较值都为`false`
5. `原始类型`和`引用类型`做比较时,引用类型会依照`ToPrimitive`规则转换为原始类型
`ToPrimitive`规则,是引用类型向原始类型转变的规则,它遵循先`valueOf`后`toString`的模式期望得到一个原始类型
如果还是没法得到一个原始类型,就会抛出 `TypeError`
**/

null == null   //true
undefined == undefined  //true
null == undefined  //true
null == 0  //false
null == false  //false
undefined == 0  //false
undefined == false  //false
null == []  //false
null == {}  //false
undefined == []  //false
undefined == {}  //false

undefined === null //false

  1. [] == []
[] == [] //false

[] == ![] //true```
// 第一步,![] 会变成 false
// 第二步,应用 规则2 ,题目变成: [] == 0
// 第三步,应用 规则5 ,[]的valueOf是0,题目变成: 0 == 0
// 所以, 答案是 true

{} == !{} //false
{} == {} //false

参照表: image.png

  1. typeof null // Object
  2. typeof NaN // number
  3. [] == 0 // true
[].valueOf().toString() // ''
Number('') // 0
  1. for in 和 for of 的区别?谁用来遍历对象,谁用来遍历数组?
  2. promise 干啥的?里面有什么方法?
待定(pending): 初始状态,既没有被兑现,也没有被拒绝。
已兑现(fulfilled): 意味着操作成功完成。
已拒绝(rejected): 意味着操作失败。

Promise.resolve()
Promise.reject()

Promise.all([promise1, promise2, promise3]).then(()=>{}) 
// 按参数顺序输出
// 如果有一个立即执行错误,其他延迟执行但正确,结果将立即变为失败

const promises = [promise1, promise2];
Promise.allsettled(promises)
// [{ status: "fulfilled", value: 3 }, { status: "rejected", reason: "foo" }]
// 输出所有的结果

Promise.race([promise1, promise2]).then((value) => {
  console.log(value);
});
// 输出最快的结果

Promise.any()
//只要有一个成功的就返回那个已经成功的 `promise`,否则就返回失败的promise 和一个AggregateError类型的实例

Promise.prototype.catch()
p.catch(function(reason) {
   // 拒绝
});

Promise.prototype.finally()
p.finally(function() {
   // 返回状态为(resolved 或 rejected)都会调用回调
}

Promise.prototype.then()
p.then(onFulfilled[, onRejected]);

p.then(value => {
  // fulfillment
}, reason => {
  // rejection
});

如果 `then` 中的回调函数
1. 返回了一个值,那么 `then` 返回的 Promise 将会成为接受状态,并且将返回的值作为接受状态的回调函数的参数值。
2. 没有返回任何值,那么 `then` 返回的 Promise 将会成为接受状态,并且该接受状态的回调函数的参数值为 `undefined`3. 抛出一个错误,那么 `then` 返回的 Promise 将会成为拒绝状态,并且将抛出的错误作为拒绝状态的回调函数的参数值。
4. 返回一个已经是接受状态的 Promise,那么 `then` 返回的 Promise 也会成为接受状态,并且将那个 Promise 的接受状态的回调函数的参数值作为该被返回的Promise的接受状态回调函数的参数值。
5. 返回一个已经是拒绝状态的 Promise,那么 `then` 返回的 Promise 也会成为拒绝状态,并且将那个 Promise 的拒绝状态的回调函数的参数值作为该被返回的Promise的拒绝状态回调函数的参数值。
6. 返回一个未定状态(`pending`)的 Promise,那么 `then` 返回 Promise 的状态也是未定的,并且它的终态与那个 Promise 的终态相同;同时,它变为终态时调用的回调函数参数与那个 Promise 变为终态时的回调函数的参数是相同的。


// 输出什么?
const promise = new Promise((resolve, reject) => {
  console.log(6)
  resolve(1)
  reject(2)
  resolve(3)
  console.log(5)
})

const promise1 = promise.then((res) => {
  console.log(res)
  return 4
}).then((res) => {
  console.log(res)
})

promise.catch((err) => {
  console.log(err)
})

promise1.then((res) => {
  console.log(res)
})
// 6 5 1 4 undefined
  1. classlist 的api
div.classList.add("foo");
div.classList.remove("foo");
div.classList.toggle("foo");
div.classList.contains("foo");
div.classList.replace("foo", "bar");
  1. set map特点 ? api? weakmap weakset 的特点?
  2. 实现 arr = [1, 2, [6, 2, [...[,,]]], [], 0] 扁平化,然后去重,然后升序排列/降序
let arr = [1, 2, [6, 2, [...[,,]]], [], 0]
let newArr = arr.flat()
let setList = [...new Set(newArr)]
setList.sort((a, b) => {return a - b})

//扁平化
function flatten(arr){
    var res = [];
    for(var i=0;i<arr.length;i++){
        if(Array.isArray(arr[i])){
            res = res.concat(flatten(arr[i]));
        }else{
            res.push(arr[i]);
        }
    }
    return res;
}
  1. 类数组转数组的方法
[...arr]
循环+利用新数组
Array.from()
Array.prototype.slice.call()
  1. 迭代器咋实现?里面有啥?
  2. 判断是不是数组
Array.isArray()
Object.prototype.toString.call()
arr instanceof Array
  1. filter find 返回值是啥
  2. 数组反转?reserve 会不会改变原数组?
reserve
数组循环

会改变原数组的:
reserve
sort
  1. vue的父子生命周期顺序
创建:
父 beforcreated -> 父 created -> 父 beforemounted -> 子 beforcreated -> 子 created -> 子 beforemounted -> 子 mounted
  1. vue2/3的响应式实现原理?3有啥好处? vue2: Object.defineProperty vue3: proxy

  2. 防抖节流

// 节流,n秒执行一次,如果重复触发,只有一次能生效
function throttle(func, time) {
  let timer = null
  return function (){
    if(!timer) {
      timer = setTimeout(() => {
        func.apply(this, [...arguments]);
        timer = null;
      }, time)
    }
  }
}

// 防抖,n秒执行一次,如果重复处罚,重新开始计时

function debounce(func, time) {
  let timer = null
  return function () {
    console.log(this)
 
    clearTimeout(timer)
    timer = setTimeout(() => {
      func.apply(this, [...arguments])
    }, time)
  }
}
  1. 模块化的发展,commonjs 有啥优缺点?es6的默认导出导入,和export的导入 es6模块化
为啥要用模块化?
作用域隔离


es6模块化
import 名称 from  模块   // 默认导入
import {xx,xx,xx}  from  模块  // 按需导入
import 名称,{xx,xx,xx} from 模块 // 默认和按需同时导入\


CommonJs (典型代表:node.js早期)
所有代码都运行在模块作用域,不会污染全局作用域
模块是同步加载的,即只有加载完成,才能执行后面的操作
模块在首次执行后就会缓存,再次加载只返回缓存结果,如果想要再次执行,可清除缓存
`require`返回的值是被输出的值的拷贝,模块内部的变化也不会影响这个值

AMD (典型代表:require.js) 所有依赖模块的语句,都定义在一个回调函数中,等到模块加载完成之后,这个回调函数才会运行

CMD (典型代表:sea.js)

UMD
用来处理commonjs、amd、cmd的兼容性差异

typescript module
提供了一个tsconfig.json 的编译器, 比如可配置moduleAMD等
默认编译成 commonjs

  1. display:none visibile:hidden opacity:0的区别?父组件visibile:hidden 子组件 visibile: visible 子组件会不会显示?
display:none 会隐藏切不占位置
visibile:hidden 隐藏但位置不变,不能触发事件
opacity:0 透明度为0 可触发监听事件

父组件visibile:hidden 子组件 visibile: visible 子组件会显示
  1. 如何获取当前时间戳
const s0 = Date.now();
const s1 = new Date().getTime()
const s2 = new Date().valueOf()
const s3 = Date.parse(new Date())

console.log(s0, s1, s2, s3)

`> 1642234229168 1642234229168 1642234229168 1642234229000`

  1. 获取时分秒的办法
//js获取当前的时分秒
let myDate = new Date();
let h = myDate.getHours(); // 获取当前小时数(0-23)
let m = myDate.getMinutes(); // 获取当前分钟数(0-59)
let s = myDate.getSeconds();// 获取当前秒数(0-59)
let timeStr = h + ':' + 'm' + 's';
  1. 性能优化?
  1. 首屏加载速度指的是什么?
解析url到首屏资源加载完毕
  1. performance?
performance.timing

  1. requestanimation 是怎么工作的?如何将不同刷新率的变成一样的?
/*
 * 已知动画总时间和总动画距离,根据刷新率,计算每次动画的距离?
 * 节流?
 */
  1. 为什么不用setTimeout做动画?
  2. opacity的兼容问题?
IE以及更早的版本支持替代的filter属性:例如 filter: Alpha(opacity = 50)
  1. 如何做浏览器降级处理的?
  2. 宽度全屏,高度为宽度的1/2,高度随着宽自适应?
  3. 不同单位的区别?
  4. 怎么做响应式?
  5. 为什么代码库大不拆分?
  6. 动态规划:零钱兑换
  7. 平方数:按灯
  8. 二分查找:实现一个Math.sqrt()

输出什么?

var name = 'window'
var p = {
  name: "Peter",
  getName: function () {
    var self = this;
    return function() {
      return self.name;
    }
  }
}
var getName = p.getName();
var _name = getName();
console.log(_name)

参考文章链接:

chinese.freecodecamp.org/news/javasc…