前端面试题35-40

本文详细解释了JavaScript中浮点数精度问题,如0.1+0.2不等于0.3的原因,以及在内存中二进制表示导致的精度丢失。同时,介绍了执行栈和执行上下文的概念,包括全局执行上下文、函数执行上下文的创建和执行阶段,以及执行上下文栈的工作原理。此外,还讨论了JavaScript的单线程特性及其原因。
摘要由CSDN通过智能技术生成

35.在JS中为什么0.2+0.1>0.3?

十进制转化为二进制(小数部分)

乘以2,取整,小数部分继续乘以2,取整,得到小数部分0为止,★将整数顺序排列★。

小数二进制转换为十进制

将 二进制0.1111转换成 十进制数

二进制            0               .               1                     1                  1                   1 

----------------------------------------------------------------------------------------------------------------

换算次方        2^(0)                     2^(-1)             2^(-2)             2^(-3)           2^(-4)

----------------------------------------------------------------------------------------------------------------

换成分数         0/2                        1/2                 1/4                 1/8               1/16

----------------------------------------------------------------------------------------------------------------

换成十进制      0         +                0.5        +       0.25        +     0.125     +   0.0625    =   0.9375

答:因为在JS中,浮点数是使用64位固定长度来表示的,其中的1位表示符号位,11位用来表示指数位,剩下的52位尾数位,由于只有52位表示尾数位。

而0.1转为二进制是一个无限循环数0.0001100110011001100......(1100循环)

0.2转为二进制是一个无限循环数0.001100110011001100......(1100循环)

由于只能存储52位尾数位,所以会出现精度缺失,把它存到内存中再取出来转换成十进制就不是原来的0.1了,就变成了0.100000000000000005551115123126,而为什么02+0.1是因为

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

// 转成十进制正好是 0.30000000000000004

36.那为什么0.2+0.3=0.5呢?

// 0.2 和 0.3 都转化为二进制后再进行计算
0.001100110011001100110011001100110011001100110011001101 +
0.0100110011001100110011001100110011001100110011001101 = 
0.10000000000000000000000000000000000000000000000000001 //尾数为大于52位

// 而实际取值只取52位尾数位,就变成了
0.1000000000000000000000000000000000000000000000000000   //0.5
答:0.2 和0.3分别转换为二进制进行计算:在内存中,它们的尾数位都是等于52位的,而他们相加必定大于52位,而他们相加又恰巧前52位尾数都是0,截取后恰好是0.1000000000000000000000000000000000000000000000000000也就是0.5

37.那既然0.1不是0.1了,为什么在console.log(0.1)的时候还是0.1呢?

答:在console.log的时候会二进制转换为十进制,十进制再会转为字符串的形式,在转换的过程中发生了取近似值,所以打印出来的是一个近似值的

38.什么是执行栈,什么是执行上下文?

执行上下文分为:

全局执行上下文
创建一个全局的window对象,并规定this指向window,执行js的时候就压入栈底,关闭浏览器的时候才弹出
函数执行上下文
每次函数调用时,都会新创建一个函数执行上下文
执行上下文分为创建阶段和执行阶段
创建阶段:函数环境会创建变量对象:arguments对象(并赋值)、函数声明(并赋值)、变量声明(不赋值),函数表达式声明(不赋值);会确定this指向;会确定作用域
执行阶段:变量赋值、函数表达式赋值,使变量对象编程活跃对象
eval执行上下文

运行eval函数中的代码时创建的执行上下文,少用且不建议使用
执行栈:

首先栈特点:先进后出
当进入一个执行环境,就会创建出它的执行上下文,然后进行压栈,当程序执行完成时,它的执行上下文就会被销毁,进行弹栈。
栈底永远是全局环境的执行上下文,栈顶永远是正在执行函数的执行上下文
只有浏览器关闭的时候全局执行上下文才会弹出

39为什么JS是单线程的?

因为JS里面有可视的Dom,如果是多线程的话,这个线程正在删除DOM节点,另一个线程正在编辑Dom节点,导致浏览器不知道该听谁的

40.箭头函数和普通函数的区别?箭头函数可以当做构造函数 new 吗?

箭头函数是普通函数的简写,但是它不具备很多普通函数的特性
第一点,this指向问题,箭头函数的this指向它定义时所在的对象,而不是调用时所在的对象
不会进行函数提升
没有arguments对象,不能使用arguments,如果要获取参数的话可以使用rest运算符
没有yield属性,不能作为生成器Generator使用
不能new
没有自己的this,不能调用call和apply
没有prototype,new关键字内部需要把新对象的_proto_指向函数的prototype
原文链接:https://blog.csdn.net/qq_33277654/article/details/112758362

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值