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

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

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

前言

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

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

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

下面就簡(jiǎn)單講述一下。

JavaScript 賦值操作基礎(chǔ)

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

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

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

.

20左到右

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

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

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

連續(xù)賦值語(yǔ)義

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

因?yàn)樵?JS 中,賦值表達(dá)式本身會(huì)返回被賦的值,所以可以寫(xiě)成鏈?zhǔn)剑?/p>

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

 賦值表達(dá)式的返回值

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

ECMAScript 規(guī)范視角

如何評(píng)估賦值表達(dá)式

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

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

步驟拆解

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

常見(jiàn)示例

1、簡(jiǎn)單鏈?zhǔn)劫x值

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、對(duì)象屬性與賦值順序

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

執(zhí)行順序:

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

重點(diǎn)示例分析

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

關(guān)鍵點(diǎn):

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

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

總結(jié)

到此這篇關(guān)于JS賦值順序的文章就介紹到這了,更多相關(guān)JS賦值順序內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(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 自定義常用方法

    在實(shí)際的js開(kāi)發(fā)過(guò)程中,我們常常會(huì)有相似或相同的需求。這時(shí)候如果沒(méi)有很好的封裝(通用功能),代碼的重復(fù)將不可避免。
    2009-08-08
  • 萬(wàn)字詳解JavaScript手寫(xiě)一個(gè)Promise

    萬(wàn)字詳解JavaScript手寫(xiě)一個(gè)Promise

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

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

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

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

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

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

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

    一文詳解前端進(jìn)階之IntersectionObserver

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

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

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

    JavaScript模板字符串用法實(shí)例

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

最新評(píng)論

东至县| 池州市| 平度市| 河北省| 万州区| 南召县| 平顶山市| 呼和浩特市| 阜阳市| 正镶白旗| 阿坝| 武强县| 湘潭市| 迁安市| 长武县| 宣威市| 津市市| 内黄县| 泸定县| 永川市| 方城县| 乌兰浩特市| 普兰店市| 云浮市| 旬邑县| 大邑县| 库车县| 桃园市| 临沧市| 任丘市| 乾安县| 隆回县| 睢宁县| 阜康市| 毕节市| 平和县| 高碑店市| 新余市| 怀来县| 济源市| 太白县|