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

從一道前端面試題理解JS對象存儲特點和運算符執(zhí)行順序

 更新時間:2026年05月06日 10:31:57   作者:程序員小寒  
在JavaScript中,運算符的優(yōu)先級和結合性決定了它們的執(zhí)行順序,優(yōu)先級高的運算符會先執(zhí)行,而具有相同優(yōu)先級的運算符則按照結合性的規(guī)則決定先后順序,這篇文章主要介紹了如何從一道前端面試題理解JS對象存儲特點和運算符執(zhí)行順序的相關資料,需要的朋友可以參考下

本文大綱

今天來看一道前端面試的代碼輸出題。

面試官提供了一段 Javascript 代碼,要求給出這段代碼運行后的輸出結果。

const obj = {
  a: 0,
};

obj['1'] = 0;
obj[++obj.a] = obj.a++;
const values = Object.values(obj);
obj[values[1]] = obj.a;
console.log(obj);

先分析這道題前,先補充兩個個前置知識點。

知識點一:對象的常規(guī)屬性 (properties) 和排序屬性 (elements)

先來看下面一段代碼:

const obj = {};
obj['b'] = 'b'
obj[100] = '100';
obj[1] = '1';
obj['a'] = 'a';
obj[50] = '50';
obj['c'] = 'c';

for (const key in obj){ 
  console.log(`key: ${key} value: ${obj[key]}`)
}
/**
 * 打印結果如下:
  key: 1 value: 1
  key: 50 value: 50
  key: 100 value: 100
  key: b value: b
  key: a value: a
  key: c value: c
 */

觀察下打印的數(shù)據(jù),很明顯屬性的設置順序并不是打印的順序,比如 b 屬性是第一個設置的,打印結果卻排在 100 后面,仔細分析他們的打印規(guī)律,可以得到如下特點:

  1. 數(shù)字類的屬性不管設置的順序先后,都會被優(yōu)先打印,而且是按照從小到大的升序進行打印的。
  2. 字符類屬性會按照設置的順序進行打印,上面我們是按照 ba、c 的順序進行設置的,打印順序也是如此。

為什么會出現(xiàn)這樣的結果呢?

這是因為 ECMAScript 規(guī)范中定義了數(shù)字屬性應該按照索引值大小升序排列,字符串屬性根據(jù)創(chuàng)建時的順序升序排列。在 V8 中數(shù)字屬性被稱為 elements,字符串屬性被稱為 properties。之所以這樣設置,主要是為了提升訪問性能。elements 對象中會按照順序存放數(shù)字屬性,類似于數(shù)組的存儲,這樣查詢的效率當然就很高了。

知識點二:JavaScript 運算符的執(zhí)行順序

JavaScript 中最常見運算符如下(運算順序從高到低排列):

  • 對象屬性訪問,比如 obj.a,obj['a']。
  • 遞增/遞減,比如 a++(后置遞增) 或 ++a(前置遞增)。
  • 算術,比如 a + 1
  • 比較,包括 <(小于)、>(大于)、<=(小于等于)、>=(大于等于),比如 a > 3。
  • 相等,包括 == 粗略相等, ===嚴格相等,!== 粗略不等,!== 嚴格不等,比如 a == 1。
  • 邏輯,也就是與或非,&(與)、|(或)、!(非),比如 a && b。
  • 三元,比如 flag ? '1' : '0'。
  • 賦值,比如 a = 1

對于單個賦值語句 LHS = RHS 的求值,根據(jù) ECMAScript 規(guī)范(ECMA-262, AssignmentExpression evaluation),對于 LeftHandSideExpression = AssignmentExpression,其計算順序如下:

  • 第一步,先得到一個 引用(Reference),即“要寫入的位置”,也就是 Evaluate LeftHandSideExpression。
  • 第二步,再計算右側的值,Evaluate AssignmentExpression。
  • 最后將第二步得到的值寫入第一步的引用當中。

也就是說,對于LHS = RHS 這樣的賦值表達式,其計算順序是左側先求值(為了知道寫到哪),右側后求值(為了知道寫什么),最后將右側的值寫入左側。

?? 注意:這里說的“左側求值”不是求它的值,而是求它的“位置”(比如屬性名、變量名等)。例如對于 obj[++obj.a],要確定屬性名,就必須先執(zhí)行 ++obj.a

寫個簡單例子:

const obj = {
  get a() {
    console.log('獲取 a 的值');
    return 1;
  },
  get b() {
    console.log('獲取 b 的值');
    return 2;
  }
}
obj[++obj.a] = obj.b++;
console.log('obj: ', obj);

我們前面說過,運算符順序是對象屬性訪問 > 遞增/遞減 > 賦值,對于賦值運算符 LHS = RHS,會先求出左側 LHS引用(Reference),再計算右側 RHS 的值,最后將右側的值賦值給左側的引用。所以用這個邏輯來分析下這段代碼的執(zhí)行順序:

  • 第一步,先取 obj.a 的值, 取到的值為 1, 然后執(zhí)行前置遞增 ++obj.a,結果為 2,然后程序就知道要往 obj2 屬性上賦值了。
  • 第二步,然后再取 obj.b 的值,執(zhí)行后置遞增 obj.b++,右側計算的值為 2。
  • 最后把右側計算的結果值 2 賦值給 obj[2] 屬性。

逐行分析代碼執(zhí)行過程

了解了這兩個知識點后,讓我們來逐行解析下這段代碼。

const obj = {
  a: 0,
};

obj['1'] = 0;
obj[++obj.a] = obj.a++;
const values = Object.values(obj);
obj[values[1]] = obj.a;
console.log(obj);
  1. 首先,我們定義了一個對象 obj,它有一個屬性 a,值為 0。
const obj = {
  a: 0,
};
  1. 接下來,我們給 obj 添加了一個屬性 1,值為 0,此時對象中有兩個屬性,a1。
obj['1'] = 0;

由于數(shù)字屬性會排在前面,此時 obj 的值為:

{
  "1": 0,
  "a": 0,
}
  1. 然后會執(zhí)行 obj[++obj.a] = obj.a++,前面我們分析過運算符的優(yōu)先級,先執(zhí)行左側 ++obj.a 得到 1,然后執(zhí)行右側 obj.a++, 由于是后置遞增,所以右側的值為 1,執(zhí)行賦值后,obj 的值為:
{
  "1": 1,
  "a": 2,
}
  1. 經過 Object.values(obj) 后,values 的值為 [1, 2]。
  2. 執(zhí)行 obj[values[1]] = obj.a ,轉換后就是 obj[2] = 2obj 的值變?yōu)椋?/li>
{
  "1": 1,
  "2": 2,
  "a": 2,
}

這就是最終的輸出結果了。

小結

該題主要考察兩個知識點:

  1. JavaScript 對象中,屬性的設置順序并不一定是循環(huán)打印順序,在 V8中,數(shù)字類的屬性在被稱為 elements(按從小到大排列存儲),字符類屬性被稱為 properties(按添加順序存儲)。
  2. JavaScript 運算符的運算順序是對象屬性訪問 > 遞增/遞減 > 賦值,對于賦值運算符 LHS = RHS,會先求出左側 LHS引用(Reference),再計算右側 RHS 的值,最后將右側的值賦值給左側的引用。

到此這篇關于從JS對象存儲特點和運算符執(zhí)行順序的文章就介紹到這了,更多相關JS對象存儲和運算符執(zhí)行順序內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • canvas實現(xiàn)繪制吃豆魚效果

    canvas實現(xiàn)繪制吃豆魚效果

    本篇文章主要分享了canvas實現(xiàn)繪制吃豆魚效果的示例代碼,具有一定的參考價值,下面跟著小編一起來看下吧
    2017-01-01
  • 微信小程序引入外部icon(阿里巴巴矢量圖標)的全過程

    微信小程序引入外部icon(阿里巴巴矢量圖標)的全過程

    在小程序中,有默認的圖標icon組件,但你會發(fā)現(xiàn)它的圖標樣式很少,可能很多時候并不能滿足我們的需求,所以這篇文章主要給大家介紹了關于微信小程序引入外部icon(阿里巴巴矢量圖標)的相關資料,需要的朋友可以參考下
    2022-09-09
  • JS Range HTML文檔/文字內容選中、庫及應用介紹

    JS Range HTML文檔/文字內容選中、庫及應用介紹

    本文的內容基本上是基于“區(qū)域范圍對象(Range objects)”這個概念來說的
    2011-05-05
  • JS閉包的幾種常見形式實例詳解

    JS閉包的幾種常見形式實例詳解

    本文通過實例代碼給大家詳細介紹了js閉包的幾種常見形式,代碼簡單易懂,非常不錯,具有參考借鑒價值,需要的朋友參考下
    2017-09-09
  • 前端Webpack配置之eval-source-map使用方法

    前端Webpack配置之eval-source-map使用方法

    eval-source-map 是 Webpack 中 devtool 選項的一種模式,它提供了一種內聯(lián) Source Map 的方式,用于開發(fā)環(huán)境中的源代碼映射,這篇文章主要介紹了前端Webpack配置之eval-source-map使用方法,需要的朋友可以參考下
    2024-12-12
  • JavaScript實現(xiàn)窗口抖動效果

    JavaScript實現(xiàn)窗口抖動效果

    抖動效果在各大網頁上都常遇到,這篇文章主要介紹了JavaScript實現(xiàn)窗口抖動效果的相關資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2016-10-10
  • 詳解tween.js的使用教程

    詳解tween.js的使用教程

    本篇文章主要介紹了詳解tween.js的使用方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09
  • JS實現(xiàn)點擊事件統(tǒng)計的簡單實例

    JS實現(xiàn)點擊事件統(tǒng)計的簡單實例

    下面小編就為大家?guī)硪黄狫S實現(xiàn)點擊事件統(tǒng)計的簡單實例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-07-07
  • JavaScript實現(xiàn)Tab欄切換功能詳解

    JavaScript實現(xiàn)Tab欄切換功能詳解

    這篇文章主要介紹了JavaScript實現(xiàn)Tab欄切換的實現(xiàn)方式,是面向對象的寫法,本文給大家分享詳細案例代碼,需要的朋友可以參考下
    2022-10-10
  • Bootstrap優(yōu)化站點資源、響應式圖片、傳送帶使用詳解3

    Bootstrap優(yōu)化站點資源、響應式圖片、傳送帶使用詳解3

    這篇文章主要介紹了Bootstrap優(yōu)化站點資源、完成響應式圖片、讓傳送帶支持手勢的相關知識,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-10-10

最新評論

徐州市| 喀喇沁旗| 宝坻区| 鲁甸县| 合阳县| 克拉玛依市| 许昌市| 淄博市| 阿拉善盟| 淄博市| 临夏市| 确山县| 南皮县| 合川市| 青海省| 海兴县| 临安市| 鄢陵县| 泾阳县| 奎屯市| 新津县| 武山县| 徐汇区| 潍坊市| 日照市| 阳山县| 琼海市| 台州市| 石狮市| 宣城市| 龙口市| 涟水县| 锡林浩特市| 南丹县| 灌南县| 平谷区| 麻江县| 汝城县| 长兴县| 武功县| 佛教|