两年经验的前端js面试题分享

238 阅读7分钟

一、基本数据类型有哪些、怎么判断、有哪些方式

  • 1.基本数据类型有:number、string、boolean、null、Undefined、Biglnt
  • 2.判断方式:
  使用typeof判断基本数据类型 :正则、{}、[]、null输出结果为object
  console.log(typeof /\d/);//object
  console.log(typeof {});//object
  console.log(typeof []);//object
  console.log(typeof (null));//object
  console.log(typeof 123);//number
  console.log(typeof true);//boolean
  console.log(typeof function () {});//function 
  console.log(typeof (undefined));//undefined
  使用instanceof判断引用数据类型
  console.log({} instanceof Object)//true
  console.log([] instanceof Array) //true
  console.log(function name(){} instanceof Function) //true
  使用constructor构造函数
  function a() {}
  let a = new b;
  console.log(a.constructor.name);//a
  console.log(b.constructor);//Function(){} 
  console.log(Function.constructor);//Function(){}
  使用原型方法Object.portotype.toString
  	Object.prototype.toString.call(12)//[boject Number]
	Object.prototype.toString.call(true)//[boject Boolean]
                                      //"[object Number]"
					    //"[object String]"
					    //"[object Object]"
					    //"[object Function]"
					    //"[object Undefined]"
					    //"[object Null]"
					    //"[object RegExp]"
		                            //"[object Boolean]"

二、0.1+0.1!=0.2 解释下js丢失精度的问题

  • 1.计算机存储小数,会先将十进制转换为二进制的科学计数法
  • 2.然后,计算机按照自己的规则存储二进制的科学计数法
  • 3.因为存储有位数限制,并且有些转换为二进制时会陷入无限循环,会造成二进制的舍入操作,那自然就会有精度问题了
# 大数字解决方案
-   使用bigInt这种数据类型
-   使用字符串这种数据类型
-   使用第三方库,比如 bignumber
# 小数计算精度解决方案
-   使用toFixed,保留小数位数,返回的是字符串。需要用parseFloat转为数值类型。但是toFixed对于有关5结尾的小数,是有问题的。所以要进行toFixed修复。
-   先放大再缩小的方式。先乘以10的倍数,转为整数,计算完成后,再除以10的倍数,转为小数。但要注意,整数不能超过js的数值范围。
-   使用第三方库 bignumber

三、什么是事件委托

  • 事件委托也叫事件代理,“事件代理”即是把原本需要绑定在子元素的响应事件(click、keydown…)委托给父元素,让父元素担当事件监听的职务。事件代理的原理是DOM元素的[事件冒泡]
  • 事件委托的优点:1. 可以大量节省内存占用,减少事件注册,比如在ul上代理所有li的click事件。2. 可以实现当新增子对象时无需再次对其绑定(动态绑定事件)
  • 事件委托的缺点:1. focus,blur之类事件本身没有冒泡机制,无法委托 2.mousemove,mouseout这类的事件,虽然存在事件冒泡,但是每次都需要计算位置,消耗很高很麻烦,同样不适用于事件委托。

四、事件循环(Event Loop)

  • JS 引擎是单线程的,直白来说就是一个时间点下 JS 引擎只能去做一件事情,而 Java 这种多线程语言,可以同时做几件事情。
  • JS 做的任务分为同步和异步两种,所谓 “异步”,简单说就是一个任务不是连续完成的,先执行第一段,等做好了准备,再回过头执行第二段,第二段也被叫做回调;同步则是连贯完成的。
1.整体的script(作为第一个宏任务)开始执行的时候,会把所有代码分为两部分:“同步任务”、“异步任务”;
2.同步任务会直接进入主线程依次执行
3.异步任务会再分为宏任务(进入宏任务队列) 和 微任务(进入微任务队列)
4.当主线程内的任务执行完毕(主线程为空时),会检查微任务的任务队列,如果有任务,就进入主线程全部执行,如果没有就从宏任务队列读取下一个宏任务执行
5.每执行完一个宏任务就清空一次微任务队列,此过程会不断重复,这就是Event Loop
### 宏任务
-   setInterval()
-   setTimeout()
-   setImmediate()
-   ajax
-   事件绑定
### 微任务
-   new Promise()后的then与catch函数
-   new MutaionObserver()
-   process.nextTickNodejs
相关题目:
setTimeout(function () {
    new Promise(function (resolve, reject) {
        console.log('异步宏任务promise');
        resolve();
    }).then(function () {
        console.log('异步微任务then')
    })
    console.log('异步宏任务');
}, 0)
new Promise(function (resolve, reject) {
    console.log('同步宏任务promise');
    resolve();
}).then(function () {
    console.log('同步微任务then')
})
console.log('同步宏任务')


答案:同步宏任务promise、同步宏任务、同步微任务then、异步宏任务promise、异步宏任务、异步微任务then
setTimeout(() => {
    console.log('异步1任务time1');
    new Promise(function (resolve, reject) {
        console.log('异步1宏任务promise');
        setTimeout(() => {
            console.log('异步1任务time2');
        }, 0);
        resolve();
    }).then(function () {
        console.log('异步1微任务then')
    })
}, 0);
console.log('主线程宏任务');
setTimeout(() => {
    console.log('异步2任务time2');
 
}, 0);
new Promise(function (resolve, reject) {
    console.log('宏任务promise');
    // reject();
    resolve();
}).then(function () {
    console.log('微任务then')
}).catch(function () {
    console.log('微任务catch')
})
console.log('主线程宏任务2');

答案:主线程宏任务、宏任务promise、主线程宏任务2、微任务then、异步1任务time1、异步1宏任务promise、异步1微任务then、异步2任务time2、异步1任务time2

五、节流和防抖 说一下他们的区别和实现方法

1.防抖:在设定的时间内触发一次事件,会在设定的时间结束之后执行该事件处理程序,如果在设定的时间内多次触发事件,则每次触发事件都会重新计时。(可以将防抖类比成电梯:第一个人进电梯之后,电梯会在5秒之后自动关闭电梯门,如果在这5秒内又有人进来了,那么电梯会重新等待5秒后再关门。)

  1. 简单理解就是:单位时间内,频繁触发一个事件,以最后一次触发为准。
防抖的应用场景
主要用来监听input输入框:我们在搜索内容的时候一般都会有搜索提示,它是通过input事件获取用户输入的内容,然后发送数据请求给后端,后端返回搜索提示内容。我们希望等待用户输入结束之后再发送请求,而不是输入一个发一次请求,这时候就需要使用防抖函数来实现
实现方式
//func 是事件处理程序,delay 是事件执行的延迟时间,单位:毫秒
    function debounce(func, delay){
      var timer = null;
      return function(){
        var that = this;
        var args = arguments
        //每次触发事件 都把定时器清掉重新计时
        clearTimeout(timer)
        timer = setTimeout(function(){
          //执行事件处理程序
          func.call(that, args)
        }, delay)
      }
    }

2. 节流:在设定的时间内多次触发事件,只会在设定的时间结束后执行一次。

  1. 简单理解就是:单位时间内,频繁触发一个事件,只会触发一次。
节流的应用场景
监听scroll滚动事件、按钮点击等等
实现方式
//func 是事件处理程序,delay 是事件执行的延迟时间,单位:毫秒
    function throttle(func, delay){
      //定义初始时间(开始触发事件的时间)
      var start = 0;
      return function(){
        var that = this;
        var args = arguments;
        //获取当前时间戳
        var current = Date.now();
        // 判断当前时间与初始时间是否超过间隔
        if(current - start >= delay){
          //执行事件处理程序
          func.call(that, args)
          //更新初始时间
          start = current;
        }
      }
    }

六、css 实现居中实现方式

<div class="father">
    <div class="son"></div>
</div>
##使用定位+margin的方式实现垂直水平居中
.father{
    width:600px;
    height:200px;
    border:1px solid #aaa;
    position:relative;
    .son{
        width:200px;
        height:100px;
        position:absolute;
        margin:auto;
    }
}
##使用定位+transform的方式实现垂直水平居中
.father{
    width:600px;
    height:200px;
    border:1px solid #aaa;
    position:relative;
    .son{
        width:200px;
        height:100px;
        position:absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
    }
}
##使用flex布局实现
.father{
    width:600px;
    height:200px;
    border:1px solid #aaa;
    display:flex;
    flex-direction: row; /* default value */
    justify-content: center; /* x-axis */
    align-items: center; /* y-axis */
}
##使用grid布局实现
.father{
    width:600px;
    height:200px;
    border:1px solid #aaa;
    display: grid;
    place-items: center;
}
##使用table布局实现
.father{
    width:600px;
    height:200px;
    border:1px solid #aaa;
    display: table;
    .son{
        display:table-cell;
        text-align:center;
        vertical-align:middle;
    }
}

七、浏览器本地存储有哪些、用过indexDB吗

八、promise相关的api 用过哪些 如何在all方法中找到失败的promise