最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

解構(gòu)賦值的危險性詳解及js不加分號竟然會導(dǎo)致報錯解決

 更新時間:2026年06月05日 09:53:27   作者:watermelo37  
JavaScript是一種解釋型的編程語言,用于在網(wǎng)頁上實現(xiàn)交互性和動態(tài)性,在JavaScript代碼中,分號是一種用于標(biāo)識語句結(jié)束的符號,這篇文章主要介紹了解構(gòu)賦值的危險性詳解及js不加分號竟然會導(dǎo)致報錯解決的相關(guān)資料,需要的朋友可以參考下

前言

在使用ES6新特性的時候,有時候會出現(xiàn)一些奇怪的bug,明明代碼寫得很基礎(chǔ),一眼就能看懂正在做什么,但是結(jié)果卻往往事與愿違,出現(xiàn)一些完全無法理解的特殊情況,不管是多少次反復(fù)檢查,還是請其他開發(fā)者幫忙檢查,亦或是詢問AI,都無法發(fā)現(xiàn)bug所在,但結(jié)果就是不對,這是為什么呢?

一、問題場景回溯

事情是這樣的:我在實現(xiàn) RandomizedSet 的時候,刪除元素時需要把數(shù)組末尾的值交換到要刪除的位置。邏輯非常清晰,順手就用了解構(gòu)賦值

RandomizedSet.prototype.remove = function (val) {
    if (this._map.has(val)) {
        let index = this._map.get(val)
        let lastIdx = this._arr.length - 1
        if (index === lastIdx) {
            this._map.delete(val)
            this._arr.pop()
            return true
        }
        let movedVal = this._arr[lastIdx]
        [this._arr[index], this._arr[lastIdx]] = [this._arr[lastIdx], this._arr[index]]
        this._arr.pop()
        this._map.delete(val)
        this._map.set(movedVal, index)
        return true
    }
    return false
};

我很自信這段代碼沒有問題——this._arr 不管是在聲明階段,還是添加和刪除階段,從頭到尾都是數(shù)字?jǐn)?shù)組。但調(diào)試時卻發(fā)現(xiàn),movedVal 的某個元素竟然變成了一個數(shù)組。

堪稱靈異事件,花費很多時間查找bug都無濟于事。

二、問題探究

不賣關(guān)子,結(jié)果真相令人哭笑不得:問題出在 let movedVal = this._arr[lastIdx] 后面缺少一個分號。修改后應(yīng)該是這樣子的:

let movedVal = this._arr[lastIdx];
[this._arr[index], this._arr[lastIdx]] = [this._arr[lastIdx], this._arr[index]]

由于 JavaScript 的自動分號插入(ASI)機制,如果不加分號,上面這段代碼在解析時會被認(rèn)為是:

let movedVal = this._arr[lastIdx] [this._arr[index], this._arr[lastIdx]] = [this._arr[lastIdx], this._arr[index]]

也就是說,JS 把 [this._arr[index], this._arr[lastIdx]] 誤認(rèn)為是對 this._arr[lastIdx] 的下標(biāo)訪問,從而整個邏輯跑偏,movedVal 自然也就莫名其妙地成了數(shù)組。這找誰說理去?

所以推薦在解構(gòu)賦值之前的語句添加分號,這樣就會可以避免錯誤解析了。

三、原理剖析

上文說了,罪魁禍?zhǔn)拙褪?JavaScript 的自動分號插入 (ASI)機制。

JS 解釋器在解析時,會嘗試自動補充分號,但它有一些固定規(guī)則:行首如果是 [ 或 (,解釋器會優(yōu)先認(rèn)為它和上一行是同一條語句,所以 [a, b] = ... 被認(rèn)為是上一行的延續(xù),而不是一條獨立的解構(gòu)賦值語句。

這個本質(zhì)上是設(shè)計不兼容導(dǎo)致的,ASI 在早期 JS 里是“容錯機制”,幫人少打幾個 “ ;” ,但在 ES6 之后,JS 語法更復(fù)雜(解構(gòu)、箭頭函數(shù)、async/await),ASI 就經(jīng)常和直覺沖突。就比如解構(gòu)賦值的 “[” 在 JS 里既可以是表達(dá)式開頭,又可能是語句延續(xù),這個時候 ASI 按照原先的設(shè)計規(guī)范就會出岔子。

說透了其實很簡單,也很好理解,但是不知道的情況下找bug是真的難熬,這種小細(xì)節(jié)問AI,AI完全回答不出來。非得自己發(fā)現(xiàn)才行。

四、拓展:JS 中必須小心分號的場景

說來慚愧,這其實不是我第一次被 ASI“坑”了。其實除了解構(gòu)賦值,還有不少典型場景:

1、行首是 [ 或 ( 時

let arr = [1, 2, 3]
[1, 2, 3].forEach(console.log) // 這里會出錯

//同理,函數(shù)調(diào)用行首是 ( 時也會出錯:
let fn = function() { console.log("hi") }
(fn)() // ← 如果上面不加分號,這里會報錯

2、行首是模板字符串(`)

和 '[和 '(' 類似,模板字符串如果寫在行首,也會被拼接到上一行:

let a = "Hello"
`world`.toUpperCase() // 被拼接到上一行

3、return / yield / throw 后換行

這幾個關(guān)鍵字恰好反過來,不管你加不加分號,后面如果直接換行,JS 會自動插入分號,導(dǎo)致返回值丟失。

function f() {
return
{ x: 1 }
}
console.log(f()) // undefined,而不是 { x: 1 }

4、自增 / 自減運算符前置

++ 和 -- 出現(xiàn)在新一行的開頭時,會被當(dāng)作上一行的表達(dá)式。

let i = 1
let j = i
++j // 被誤解為 i++

5、解構(gòu)賦值出現(xiàn)在新行(上述場景)

let x = 1
let y = 2
[x, y] = [y, x] // 語法被誤解

6、鏈?zhǔn)秸{(diào)用 / IIFE 立即執(zhí)行函數(shù)

一個函數(shù)如果前置寫了 “.” ,那么就會被接到上一行作為鏈?zhǔn)秸{(diào)用,這要是不小心加了一點,檢查的時候可就費勁咯。

// 鏈?zhǔn)秸{(diào)用場景,不小心多寫了個.
let a = b + c
.toString()
// 相當(dāng)于let a = b + c.toString();

// IIFE場景,會直接報錯
let a = 1
(function() { console.log("IIFE") })()

五、結(jié)語

JavaScript 的 ASI 機制讓“省略分號”看似優(yōu)雅,但在某些場景下卻暗藏殺機。尤其是:

  • 行首是 [、(、`、+、- 的情況;

  • return / throw / yield 后直接換行;

  • 解構(gòu)賦值單獨占一行。

我的建議是:要么保持“全加分號”的風(fēng)格,要么在無分號風(fēng)格下,遇到危險場景一定要小心換行。不然,像我一樣被 movedVal 莫名其妙變成數(shù)組,還要花半天 debug,可就太冤了。

只有鍛煉思維才能可持續(xù)地解決問題,只有思維才是真正值得學(xué)習(xí)和分享的核心要素。如果這篇博客能給您帶來一點幫助,麻煩您點個贊支持一下,還可以收藏起來以備不時之需,有疑問和錯誤歡迎在評論區(qū)指出~

到此這篇關(guān)于解構(gòu)賦值的危險性詳解及js不加分號竟然會導(dǎo)致報錯解決的文章就介紹到這了,更多相關(guān)js不加分號導(dǎo)致報錯內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 用純JS實現(xiàn)二級菜單效果

    用純JS實現(xiàn)二級菜單效果

    這篇文章主要為大家詳細(xì)介紹了用純JS實現(xiàn)二級菜單效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-04-04
  • js通過Date對象實現(xiàn)倒計時動畫效果

    js通過Date對象實現(xiàn)倒計時動畫效果

    這篇文章主要為大家詳細(xì)介紹了js通過Date對象實現(xiàn)倒計時動畫效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-10-10
  • JavaScript函數(shù)執(zhí)行、作用域鏈以及內(nèi)存管理詳解

    JavaScript函數(shù)執(zhí)行、作用域鏈以及內(nèi)存管理詳解

    這篇文章主要介紹了JavaScript函數(shù)執(zhí)行、作用域鏈以及內(nèi)存管理的知識,文章內(nèi)容非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • ajax 同步請求和異步請求的差異分析

    ajax 同步請求和異步請求的差異分析

    ajax 同步請求和異步請求的差異分析,需要的朋友可以參考下。
    2011-07-07
  • webpack4 css打包壓縮問題的解決

    webpack4 css打包壓縮問題的解決

    本篇文章主要介紹了webpack4 css打包壓縮問題的解決,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-05-05
  • JavaScript實現(xiàn)京東快遞單號查詢

    JavaScript實現(xiàn)京東快遞單號查詢

    這篇文章主要為大家詳細(xì)介紹了JavaScript實現(xiàn)京東快遞單號查詢,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-11-11
  • js實現(xiàn)時鐘定時器

    js實現(xiàn)時鐘定時器

    這篇文章主要為大家詳細(xì)介紹了js實現(xiàn)時鐘定時器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-03-03
  • js簡單粗暴的發(fā)布訂閱示例代碼

    js簡單粗暴的發(fā)布訂閱示例代碼

    這篇文章主要給大家介紹了js簡單粗暴的發(fā)布訂閱的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • javascript 建設(shè)銀行登陸鍵盤

    javascript 建設(shè)銀行登陸鍵盤

    javascript模擬鍵盤輸入密碼
    2008-06-06
  • My Desktop :) 桌面式代碼

    My Desktop :) 桌面式代碼

    My Desktop 桌面式 代碼
    2008-12-12

最新評論

和静县| 买车| 加查县| 阿瓦提县| 黑水县| 侯马市| 漳平市| 江川县| 天峻县| 寿阳县| 新巴尔虎左旗| 文成县| 光山县| 龙口市| 海丰县| 廉江市| 炉霍县| 应城市| 新蔡县| 南阳市| 额尔古纳市| 无锡市| 阿荣旗| 葵青区| 故城县| 达孜县| 阳谷县| 巨鹿县| 佛冈县| 孝义市| 夹江县| 义马市| 元阳县| 和林格尔县| 永靖县| 龙门县| 武清区| 吴旗县| 宜丰县| 隆德县| 承德县|