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

一文詳解令人抓狂的JS賦值順序

 更新時間:2025年08月25日 11:34:56   作者:代碼里的小貓咪  
在JavaScript編程語言中,變量賦值是基礎(chǔ)且核心的概念,正確理解和運用變量賦值不僅關(guān)系到代碼的準確性,還影響著代碼的性能和可維護性,這篇文章主要介紹了JS賦值順序的相關(guān)資料,需要的朋友可以參考下

前言

你可能以為自己已經(jīng)非常熟悉 JavaScript 的賦值操作了,但這一行代碼:

var a = { n: 1 };
var b = a;
a.x = a = { n: 2 };

卻讓無數(shù)開發(fā)者陷入沉思:到底是先給 a.x 賦值,還是先給 a 重新賦值?為什么 console.log(b.x) 是一個對象,而 a.x 卻是 undefined?這不是語法問題,而是 JavaScript 底層執(zhí)行機制的奇妙。

下面就簡單講述一下。

JavaScript 賦值操作基礎(chǔ)

運算符優(yōu)先級與結(jié)合性

賦值運算符(=、+=、-=) 在 JavaScript 中是 右結(jié)合(right-to-left)的。這意味著表達式 a = b = c 會先計算右側(cè)的 b = c,再把結(jié)果賦給 a。

運算符優(yōu)先級結(jié)合性
=3右到左
+, -13左到右

.

20左到右

左值(L-value)與右值(R-value)

  •  左值:表達式的“賦值目標(biāo)”,例如變量、對象屬性、數(shù)組元素。
  • 右值:表達式的“計算結(jié)果”,例如字面量、函數(shù)返回值、其他表達式。

賦值時,JS 引擎要分別評估左值(確定要寫到哪里)和評估右值(計算要寫什么),然后才執(zhí)行寫入。

連續(xù)賦值語義

為什么 a = b = c 能連續(xù)寫?

因為在 JS 中,賦值表達式本身會返回被賦的值,所以可以寫成鏈式:

// 步驟拆解:
b = c        // 返回 c
a = (b = c)  // 再把 c 賦給 a

 賦值表達式的返回值

  • 表達式 x = y 的求值結(jié)果就是“被賦的值 y”。
  • 因此 a = b = 5 相當(dāng)于 a = 5; b = 5;,且整個表達式的值為 5。
a = b = 5;
console.log(a, b, (a = b = 5)); // 5 5 5

ECMAScript 規(guī)范視角

如何評估賦值表達式

根據(jù) ECMAScript® Language Specification(ECMA-262):

  1. 評估 AssignmentExpression:先識別運算符右側(cè)的“AssignmentExpression”
  2. 評估左值:調(diào)用 GetValue 獲取右側(cè)的值
  3. 分辨目標(biāo):調(diào)用 PutValue 將值寫入左值目標(biāo)
  4. 返回值:整個表達式的值為所寫入的值

步驟拆解

Function EvaluateAssignmentExpression(expr):
  If expr is “LeftHandSide = RightHandSide” then:
    // 1. 先評估右側(cè),得到一個值 R
    R = Evaluate(RightHandSide)
    // 2. 再評估左側(cè),得到一個引用 L
    L = ResolveReference(LeftHandSide)
    // 3. 將 R 寫入 L
    PutValue(L, R)
    // 4. 返回 R 作為整個表達式的值
    return R

常見示例

1、簡單鏈式賦值

let x, y, z;
x = y = z = 100;
console.log(x, y, z); // 100 100 100

執(zhí)行順序:

  1. z = 100  → 返回 100
  2. y = (z = 100) → 返回 100
  3. x = (y = (z = 100)) → 返回 100

2、對象屬性與賦值順序

let obj = { a: 1 };
obj.b = obj.a = 2;
console.log(obj); // { a: 2, b: 2 }

執(zhí)行順序:

  1.  先計算 obj.a = 2,寫入 a,返回 2。
  2. 再執(zhí)行 obj.b = <返回值 2>。

重點示例分析

var a = { n: 1 };
var b = a;
a.x = a = { n: 2 };

console.log(a.x);
console.log(b.x);

詳解解析:

var a = { n: 1 };  // [Obj1]
var b = a;         // b ? [Obj1]
a.x = a = { n: 2 };  
  1. 解析左側(cè)目標(biāo)(Capture LHS)
    1. 引擎先看到整個賦值表達式 a.x = …,此時 a 仍指向最初的對象 [Obj1]。
    2. “目標(biāo)位置”鎖定為:對象 [Obj1] 的屬性 x。
  2. 執(zhí)行右側(cè)賦值(Evaluate RHS)
    1. 新建一個對象字面量 { n:2 },記為 [Obj2]。
    2. 把 [Obj2] 賦給變量 a,此刻 a 從指向 [Obj1] 變?yōu)橹赶?[Obj2]。
    3. 賦值表達式 a = [Obj2] 的返回值是這個新對象 [Obj2]。
  3. 寫入屬性(Perform original “.x = …”)
    1. 雖然此時 a 已經(jīng)指向 [Obj2],但左側(cè)“目標(biāo)”早已捕獲,仍是 [Obj1].x 這個位置。
    2. 因此,將右側(cè)返回的 [Obj2] 寫入到原始對象 [Obj1] 的 x 屬性上:Obj1.x = Obj2。
  4. 查看最終結(jié)果
    1. a 指向 [Obj2],所以 a.x 查的是 [Obj2].x ——該對象上沒有 x 屬性,結(jié)果 undefined。
    2. b 依舊指向最初的 [Obj1],它的 x 屬性被寫入了 [Obj2],所以 console.log(b.x) 輸出 { n: 2 }。

關(guān)鍵點:

  • 左側(cè)目標(biāo)先捕獲:賦值表達式開始時就確定屬性寫入位置,不受后續(xù)變量指向變化影響。
    • 左側(cè) a.x 在賦值之前就要解析“引用”,此時 a 仍指向舊對象;
    • 右側(cè) a = tmp 改變了 a 引用,但不會影響已經(jīng)捕獲的“屬性寫入位置”。
  • 賦值表達式返回值:a = {n:2} 返回新的對象引用,用于后續(xù)“屬性賦值”。
  • 順序原則:先捕獲 LHS,再執(zhí)行 RHS 并返回值,最后將返回值寫入先前捕獲的 LHS。

這樣,一眼就能看清變量指向與屬性寫入的“先后關(guān)系”,避免踩坑。

總結(jié)

到此這篇關(guān)于JS賦值順序的文章就介紹到這了,更多相關(guān)JS賦值順序內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • JS限制文本框只能輸入數(shù)字和字母方法

    JS限制文本框只能輸入數(shù)字和字母方法

    這篇文章主要介紹了JS限制文本框只能輸入數(shù)字和字母方法,本文給出了限制只能輸入數(shù)字、限制只能輸入字母、限制只能輸入數(shù)字和字母3種腳本,需要的朋友可以參考下
    2015-02-02
  • Add a Table to a Word Document

    Add a Table to a Word Document

    Add a Table to a Word Document...
    2007-06-06
  • javascript 自定義常用方法

    javascript 自定義常用方法

    在實際的js開發(fā)過程中,我們常常會有相似或相同的需求。這時候如果沒有很好的封裝(通用功能),代碼的重復(fù)將不可避免。
    2009-08-08
  • 萬字詳解JavaScript手寫一個Promise

    萬字詳解JavaScript手寫一個Promise

    這篇文章主要介紹了萬字詳解JavaScript手寫一個Promise,Promise就是一個類,在執(zhí)行這個類的時候,需要傳遞一個執(zhí)行器(回調(diào)函數(shù))進去,執(zhí)行器會立即執(zhí)行
    2022-07-07
  • 微信小程序web-view環(huán)境下H5跳轉(zhuǎn)小程序頁面方法實例代碼

    微信小程序web-view環(huán)境下H5跳轉(zhuǎn)小程序頁面方法實例代碼

    微信小程序是一種全新的連接用戶與服務(wù)的方式,它可以在微信內(nèi)被便捷地獲取和傳播,同時具有出色的使用體驗,下面這篇文章主要給大家介紹了關(guān)于微信小程序web-view環(huán)境下H5跳轉(zhuǎn)小程序頁面方法的相關(guān)資料,需要的朋友可以參考下
    2022-08-08
  • JS+HTML實現(xiàn)經(jīng)典游戲吃豆人

    JS+HTML實現(xiàn)經(jīng)典游戲吃豆人

    吃豆游戲可以說是我們80,90后共同的回憶錄,小時候常常在學(xué)習(xí)機上玩,所以也就有了強烈的欲望去寫。所以本文將利用JS+HTML實現(xiàn)這一經(jīng)典游戲,需要的可以參考一下
    2022-04-04
  • 基于bootstrap按鈕式下拉菜單組件的搜索建議插件

    基于bootstrap按鈕式下拉菜單組件的搜索建議插件

    這篇文章主要為大家詳細介紹了基于bootstrap按鈕式下拉菜單組件的搜索建議插件,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-03-03
  • 一文詳解前端進階之IntersectionObserver

    一文詳解前端進階之IntersectionObserver

    這篇文章主要為大家介紹了前端進階之IntersectionObserver示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-04-04
  • Bootstrap導(dǎo)航簡單實現(xiàn)代碼

    Bootstrap導(dǎo)航簡單實現(xiàn)代碼

    這篇文章主要介紹了Bootstrap導(dǎo)航的簡單實現(xiàn)代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-03-03
  • JavaScript模板字符串用法實例

    JavaScript模板字符串用法實例

    在ES6之前我們都使用單引號或者雙引號來包裹字符串,當(dāng)我們想要在字符串中加入變量時,不能直接寫在字符串里,而是需要通過字符串拼接的方式來往字符串中加入變量,這篇文章主要給大家介紹了關(guān)于JavaScript模板字符串用法的相關(guān)資料,需要的朋友可以參考下
    2022-11-11

最新評論

招远市| 忻州市| 河北省| 岑溪市| 陈巴尔虎旗| 麟游县| 萨迦县| 文昌市| 宣恩县| 黔江区| 郓城县| 封丘县| 瑞安市| 琼海市| 尤溪县| 东台市| 安国市| 姚安县| 太白县| 新密市| 东光县| 蓝田县| 康保县| 宣武区| 岑巩县| 荥阳市| 密云县| 武夷山市| 东乡县| 青冈县| 汉中市| 肇庆市| 府谷县| 连城县| 云南省| 曲阳县| 北流市| 聂荣县| 高清| 龙泉市| 凭祥市|