你可能不知道的前端冷知识

你可能不知道的前端冷知识

此文档主要记录开发过程当中有一些不知其因此然的东西,将这些东西进行更深刻的学习,并记录在此。对于知识咱们要知其然知其因此然。

关于跳出循环

  • for循环只能使用continue结束本次循环,break结束当前循环。不能使用return,会报错
  • forEach循环不能使用continue和break会报错,return没法结束循环(只能达到continue的效果),想结束foreach循环只能抛出错误
for (let i = 1; i < 3; i++) {
  if (i === 2) {
    return // Uncaught SyntaxError: Illegal return statement
  }
  console.log(i)
}
console.log('end')

return的做用是指定函数的返回值,在这里for循环的外部没有函数包裹,因此会报错,开发过程当中有不少在循环中return的状况,这里咱们要弄清楚前端

let arr = ['a', 'b', 'c', 'd']

arr.forEach((ele, index) => {
  if (index === 2) {
    return // 这里若是改为break/continue都会报错
  }
  console.log(ele)
})

console.log('end')
// 输出结果: a, b, d, end

从上面的代码中能够看出,return的效果只是结束了当次循环,并无跳出循环函数

forEach()没法在全部元素都传递给调用的函数以前终止遍历 -----摘抄《JavaScript权威指南》

解决方法:使用every或者some来代替forEach,或者使用try catch将循环包裹在循环内部抛出错误来结束学习

0.1+0.2为何不等于0.3

console.log(0.1+0.2)
// 输出结果: 0.30000000000000004

经过查阅资料得知JavaScript内部采用的IEEE 754标准,number类型默认为双精度浮点型(64位),而后我发现了如下的问题:code

  • 首先咱们都知道计算机内部存储是采用的二进制
  • 将0.1转为二进制是无限循环小数,0.2也是无线循环小数,在存储的过程当中有没有可能会出现精度丢失呢
let a = 0.1
console.log(a.toString(2))
// 输出结果: 0.0001100110011001100110011001100110011001100110011001101

let b = 0.2
console.log(b.toString(2))
// 输出结果: 0.001100110011001100110011001100110011001100110011001101

let c = 0.1+0.2
console.log(c.toString(2))
// 输出结果: 0.0100110011001100110011001100110011001100110011001101

let d = 0.3
console.log(d.toString(2))
// 输出结果: 0.010011001100110011001100110011001100110011001100110011

console.log(Math.pow(2, 50) + 0.1)
// 输出结果: 1125899906842624
console.log(Math.pow(2, 49) + 0.1)
// 输出结果: 562949953421312.1

带着疑问通过一系列尝试,得出结论在涉及到长度溢出的时候会出现精度丢失问题,当长度溢出会默认作截取,从上面的输出中能够看出0.1+0.2转成二进制后大于0.3直接转二进制.当整数部分溢出也会出现截取现象对象

==和===的区别

为何ESLint推荐使用===代替==呢,确定是有其中的缘由的
  • == 表明相等,若是==两边是不一样类型的,会隐式的转化为相同类型的进行比较
  • === 表明严格相等, 若是===两边是不一样类型直接为false
console.log(0 == false) // true
console.log(0 === false) // false
console.log(Number(false)) // 0

从上面的输出能够看出, 0==false中间经历了一次隐式的Number(false)将==两边都转化为数字再进行比较的,而===两边类型不一样直接为false,那么隐式的类型转换有什么弊端呢ip

let x = 1
let obj = {
  valueOf: () => {
    x = 2
    return 0 
  }
}
console.log(obj == 0, x) // true, 2
// 可能致使意料以外的改变

以上代码中我并不想去改变x的值,可是obj转number的时候,obj会调用自身的valueOf方法,致使了x值的改变,此次改变是意料以外的开发

let x = 1
let obj = {
  valueOf: () => {
    return {}
  },
  toString: () => {
    return {}
  }
}
console.log(obj == 0, x)
// Uncaught TypeError: Cannot convert object to primitive value
// 可能会出现意料以外的报错

当valueOf和toString都没有返回时,会抛出异常文档

对象转化成数字的规则:it

  • 若是对象有valueOf方法,则调用该方法,并返回相应的结果
  • 当调用valueOf返回的依然不是数字,则会调用对象的toString方法,并返回相应的结果
  • 不然抛出异常
相关文章
相关标签/搜索