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

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

此文檔主要記錄開發過程當中有一些不知其因此然的東西,將這些東西進行更深刻的學習,並記錄在此。對於知識咱們要知其然知其因此然。

關於跳出循環

  • 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方法,並返回相應的結果
  • 不然拋出異常
相關文章
相關標籤/搜索