这篇博客主要用来记载我不会的面试题:想到就更.
2019.6.24 真是惭愧,本来应该会的东西,怎么就成了造核弹呢,自己还是要虚心,如果只想着混日子,那么迟早有一天,会遭到报应,比如这个日子,我怀着极大的烦躁去等待着一个我不知道的结果——我很可能没有年终奖了。
第一题:11月27日.if(0.1 + 0.2 == 0.3) {
alert("yes");
}
else{
alert("false")
}
会输出false,为什么?
同理还有0.1 + 0.2 === 0.3 也是不对的,为什么?
我们可以先看一下js的输出结果:0.1+0.2=0.30000000000000004.实际上,这是一个精度丢失的问题.这些语言中的数字都是以 IEEE 754 双精度 64 位浮点数 来存储的,它的表示格式为:(s) * (m) * (2^e) ,s是符号位,表示正负。m 是尾数,有 52 bits。e 是指数,有 11 bits,e 的范围是 [-1074, 971](ECMAScript 5 规范),这样其实很容易推出 Javascript 能表示的最大数为:1 * (Math.pow(2, 53) - 1) * Math.pow(2, 971) = 1.7976931348623157e+308,最小的数为1 * 1 * Math.pow(2, -1074) = 5e-324.
我们都知道,计算机中的数字都是以二进制存储的,如果要计算 0.1 + 0.2 的结果,计算机会先把 0.1 和 0.2 分别转化成二进制,然后相加,最后再把相加得到的结果转为十进制。
我们先把 0.1 和 0.2 分别转化为二进制,十进制转为二进制这里就不多说了,整数部分 "除二取余,倒序排列",小数部分 "乘二取整,顺序排列"。也可以用 Javascript 的 toString(2)
方法验证转换的结果。// 0.1 转化为二进制 0.0 0011 0011 0011 0011...(0011循环)
// 0.2 转化为二进制 0.0011 0011 0011 0011 0011...(0011循环)
第二题:
这一段js代码的结果是什么:
for
(var i=
0
;i<
3
;++i){
setTimeout(function(){
console.log(i);
},
100
);
}
答案是3,3,3
这个题主要涉及两个知识点,一个是异步加载问题,另一个是作用域问题。、
第一:js的加载方式分为同步加载和异步加载,在执行顺序中,同步加载会一个一个执行,而异步加载会先进入队列,在执行完同步后再执行异步。那么settimeout本身是一个延时执行函数,在本代码中是每次循环执行的100ms后进入待执行队列。故,这三次执行均在循环结束后才执行。
第二:console.log(i)中的i在console的同级中没有找到的话会跳到上级去寻找,上级找不到会跳到再上级去寻找,也就是说这个i实际上是找到的循环之后的i,也就是3. 0,1,2,3,3 = 3 退出循环,所以是3.
综合考虑以上两个知识点,结果就是三次timeout在循环执行完毕后执行,同时log(i)一直在寻找作用域,最后找到了i=3身上,所以此题答案是3,3,3