<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # 1.JS 數字精讀丟失問題 參考鏈接:[https://www.cnblogs.com/snandy/p/4943138.html](https://www.cnblogs.com/snandy/p/4943138.html) ## 常見的數字精讀丟失的情況 1.兩個浮點數相加 ```js console.log(0.1 + 0.2 !== 0.3) // true console.log(0.1 + 0.2) // 0.30000000000000004 ``` 2.大整數運算(多少位?) ```js console.log(9999999999999999 === 10000000000000001) // true var x = 9007199254740992 console.log(x + 1 === x) // true ``` 3.toFixed() 沒有四舍五入,此外 toFixed 還有一些兼容性問題 ```js console.log(1.335.toFixed(2)) // 1.33 ``` ## 原因 JS 遵循[IEEE 754](https://en.wikipedia.org/wiki/IEEE_floating_point)規范,采用雙精度存儲(double precision),占用 64 bit。如圖 ![](https://box.kancloud.cn/20cfb7d2c57d2aa24f53aeb9865a1ab6_1098x78.png) - 1位用來表示符號位 - 11位用來表示指數 - 52位表示尾數 浮點數,比如 ```js 0.1 >> 0.0001 1001 1001 1001…(1001無限循環) 0.2 >> 0.0011 0011 0011 0011…(0011無限循環) ``` 此時只能模仿十進制進行四舍五入了,但是二進制只有 0 和 1 兩個,于是變為 0 舍 1 入。這即是計算機中部分浮點數運算時出現誤差,丟失精度的根本原因。 大整數的精度丟失和浮點數本質上是一樣的,尾數位最大是 52 位,因此 JS 中能精準表示的最大整數是 Math.pow(2, 53),十進制即 9007199254740992。 大于 9007199254740992 的可能會丟失精度 ```js 9007199254740992 >> 10000000000000...000 // 共計 53 個 0 9007199254740992 + 1 >> 10000000000000...001 // 中間 52 個 0 9007199254740992 + 2 >> 10000000000000...010 // 中間 51 個 0 ``` ## 解決方案 對于整數,前端出現問題的幾率可能比較低,畢竟很少有業務需要需要用到超大整數,只要運算結果不超過 Math.pow(2, 53) 就不會丟失精度。(如果遇到一般會用字符串來替代?) 對于小數,前端出現問題的幾率還是很多的,尤其在一些電商網站涉及到金額等數據。解決方式:把小數放到位整數(乘倍數),再縮小回原來倍數(除倍數) ```js // 0.1 + 0.2 (0.1*10 + 0.2*10) / 10 == 0.3 // true ``` 對于 toFixed 方法出現的問題 ```js /** * * @param {*} num 需要轉化的數值 * @param {*} s 保留到小數點后第幾位 */ function toFixed (num, s) { let times = Math.pow(10, s) let des = num * times + 0.5 des = parseInt(des, 10) / times return des + '' } console.log(toFixed(1.335, 2)) // 1.34 ``` >TODO:這里的解決方案感覺不是很好,有空再找找... # 2.幾個細節題 ```js // this 指向 var obj = { name: 'foo', fun1: function () { console.log(this.name) }, fun2: () => { console.log(this.name) } } var fun3 = obj.fun1 fun3() obj.fun1() obj.fun2() ``` ```js // 事件循環 - resolve 之后是否會繼續往下執行? setTimeout(function () { console.log('a') }) var p = new Promise(function (resolve, reject) { console.log('b') resolve() console.log('c') }) p.then(function () { console.log('d') }) console.log('e') ``` ```js // 原型鏈 構造函數的 __proto__ 指向什么呢? Function.prototype.a = 1 Object.prototype.a = 2 Object.a = ? ``` # 3.模擬實現 lodash 中的 \_.get() 函數 模擬實現 lodash 中的 \_.get() 函數,實現如下傳入參數取值效果 ```js function get() { // 請補全函數參數和實現邏輯 } const obj = { selector: { to: { toutiao: 'FE coder' } }, target: [1, 2, { name: 'byted' }] }; // 運行代碼 get(obj, 'selector.to.toutiao', 'target[0]', 'target[2].name') // 輸出結果:// ['FE coder', 1, 'byted'] ``` 勉強實現了 ```js function get (obj, ...args) { const res = [] // 存儲返回結果 const params = args params.forEach(item => { // 'selector.to.toutiao' , 'target[0]', 'target[2].name' let splitItem = item.split('.') // -> ['selector', 'to', 'toutiao'], ['target[0]'], ['target[2], 'name'] let temp = null splitItem.forEach(value => { let index = value.indexOf('[') // case of 'target[0]' if (index !== -1) { let num = parseInt(value.substring(index + 1)) // 數組下標 Number 類型 let attr = value.substring(0, index) temp = temp === null ? obj[attr][num] : temp[attr][num] } else { temp = temp === null ? obj[value] : temp[value] // obj.selector.to.toutiao } }) res.push(temp) }) return res } console.log(get(obj, 'selector.to.toutiao', 'target[0]', 'target[2].name')) ``` # 4.找出頁面出現最多的標簽 你知道 `document.getElementsByTagName('*')`的用法嗎? ```js // 獲取元素列表,以鍵值對的形式存儲為一個對象 function getElements () { // 如果把特殊字符串 "*" 傳遞給 getElementsByTagName() 方法 // 它將返回文檔中所有元素的列表,元素排列的順序就是它們在文檔中的順序。 // 返回一個 HTMLCollection - 類數組對象 const nodes = document.getElementsByTagName('*') const tagsMap = {} for (let i = 0, len = nodes.length; i < len; i++) { let tagName = nodes[i].tagName if (!tagsMap[tagName]) { tagsMap[tagName] = 1 } else { tagsMap[tagName] ++ } } return tagsMap } // n 為要選取的標簽個數 - 即出現次數前 n 的標簽名 // 將上面的方法獲取的對象的鍵值對取出組成數組,按出現次數排序 function sortElements (obj, n) { const arr = [] const res = [] for (let key of Object.keys(obj)) { arr.push({ tagName: key, count: obj[key] }) } // 冒泡 for (let i = arr.length - 1; i > 0; i--) { for (let j = 0; j < i; j++) { if (arr[j].count < arr[j + 1].count) { // 升序 swap(arr, j, j + 1) } } } for (let i = 0; i < n; i++) { res.push(arr[i].tagName) } return res } function swap (arr, index1, index2) { let temp = arr[index1] arr[index1] = arr[index2] arr[index2] = temp } let res = sortElements(getElements(), 2) console.log(res) ``` # 5.細節問題 以下代碼的執行結果是什么? ```js function func() { var a = b = 1; } func(); console.log(a); console.log(b); ``` 答案:error,1 解析:b 沒有 var 為全局變量,var a = b 局部變量外部訪問不到 # 6.fetch 本身不支持 timeout,能否對其進行封裝使其支持 timeout? 參考:[https://imweb.io/topic/57c6ea35808fd2fb204eef63](https://imweb.io/topic/57c6ea35808fd2fb204eef63) ```js /** * 包裝 fetch 方法,使其支持 timeout * @param {Promise} fetch_promise fetch 請求 * @param {Numebr} timeout 超時時間設置 */ function _fetch (fetch_promise, timeout) { var abort_fn = null // 這是一個可以被 reject 的 promise var abort_promise = new Promise(function (resolve, reject) { abort_fn = function () { reject('abort promise') } }) // 這里使用 Promise.race, 以最快 resolve 或 reject 的結果來傳入后續綁定的回調 var abortable_promise = Promise.race([ fetch_promise, abort_promise ]) setTimeout(() => { abort_fn() }, timeout) return abortable_promise } // usage _fetch(fetch('http://test.com'), 2000) .then(res => { console.log(res) }) .catch(err => { console.log(err) }) ```
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看