js每日一问(9)

50 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第19天,点击查看活动详情

一。说说 Javascript 数字精度丢失的问题,如何解决?

一个经典的面试题

0.1 + 0.2 === 0.3 // false

为什么是false呢?

比如一个数 1÷3=0.33333333......

3会一直无限循环,数学可以表示,但是计算机要存储,方便下次取出来再使用,但0.333333...... 这个数无限循环,再大的内存它也存不下,所以不能存储一个相对于数学来说的值,只能存储一个近似值,当计算机存储后再取出时就会出现精度丢失问题

浮点数:“浮点数”是一种表示数字的标准,整数也可以用浮点数的格式来存储

JavaScript中,现在主流的数值类型是Number,而Number采用的是IEEE754规范中64位双精度浮点数编码

javascript语言中,0.1 和 0.2 都会转化成二进制后再进行运算

// 0.1 和 0.2 都转化成二进制后再进行运算
0.00011001100110011001100110011001100110011001100110011010 +
0.0011001100110011001100110011001100110011001100110011010 =
0.0100110011001100110011001100110011001100110011001100111// 转成十进制正好是 0.30000000000000004

解决方案:使用 toPrecision 凑整并 parseFloat 转成数字后再显示

可以封装成方法:

function strip(num, precision = 12) {
  return +parseFloat(num.toPrecision(precision));
}

二。什么是防抖和节流?有什么区别?如何实现?

是什么:

本质上是优化高频率执行代码的一种手段。

如:浏览器的 resizescrollkeypressmousemove 等事件在触发时,会不断地调用绑定在事件上的回调函数,极大地浪费资源,降低前端性能

节流:指定的时间内只能触发一次

防抖:指定的时间后才能触发第二次

封装节流函数:

function throttled1(fn, delay = 500) {
    let oldtime = Date.now()
    return function (...args) {
        let newtime = Date.now()
        if (newtime - oldtime >= delay) {
            fn.apply(null, args)
            oldtime = Date.now()
        }
    }
}

封装防抖函数:

function debounce(func, wait) {
    let timeout;
​
    return function () {
        let context = this; // 保存this指向
        let args = arguments; // 拿到event对象
​
        clearTimeout(timeout)
        timeout = setTimeout(function(){
            func.apply(context, args)
        }, wait);
    }
}