1. <ul id="0c1fb"></ul>

      <noscript id="0c1fb"><video id="0c1fb"></video></noscript>
      <noscript id="0c1fb"><listing id="0c1fb"><thead id="0c1fb"></thead></listing></noscript>

      99热在线精品一区二区三区_国产伦精品一区二区三区女破破_亚洲一区二区三区无码_精品国产欧美日韩另类一区

      RELATEED CONSULTING
      相關(guān)咨詢
      選擇下列產(chǎn)品馬上在線溝通
      服務(wù)時(shí)間:8:30-17:00
      你可能遇到了下面的問題
      關(guān)閉右側(cè)工具欄

      新聞中心

      這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
      JavaScript中Object和Map有哪些區(qū)別

      這篇文章主要講解了“JavaScript中Object和Map有哪些區(qū)別”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“JavaScript中Object和Map有哪些區(qū)別”吧!

      成都創(chuàng)新互聯(lián)公司是一家專業(yè)提供洛浦企業(yè)網(wǎng)站建設(shè),專注與成都網(wǎng)站建設(shè)、成都網(wǎng)站設(shè)計(jì)、H5響應(yīng)式網(wǎng)站、小程序制作等業(yè)務(wù)。10年已為洛浦眾多企業(yè)、政府機(jī)構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)站設(shè)計(jì)公司優(yōu)惠進(jìn)行中。

      用法對比

      對于 Object 而言,它鍵(key)的類型只能是字符串,數(shù)字或者 Symbol;而對于 Map 而言,它可以是任何類型。(包括 Date,Map,或者自定義對象)

      Map 中的元素會保持其插入時(shí)的順序;而 Object 則不會完全保持插入時(shí)的順序,而是根據(jù)如下規(guī)則進(jìn)行排序:

      •   非負(fù)整數(shù)會最先被列出,排序是從小到大的數(shù)字順序

      •   然后所有字符串,負(fù)整數(shù),浮點(diǎn)數(shù)會被列出,順序是根據(jù)插入的順序

      •   最后才會列出 Symbol,Symbol 也是根據(jù)插入的順序進(jìn)行排序的

      讀取 Map 的長度很簡單,只需要調(diào)用其 .size() 方法即可;而讀取 Object 的長度則需要額外的計(jì)算:Object.keys(obj).length

      Map 是可迭代對象,所以其中的鍵值對是可以通過 for of 循環(huán)或 .foreach() 方法來迭代的;而普通的對象鍵值對則默認(rèn)是不可迭代的,只能通過 for in 循環(huán)來訪問(或者使用 Object.keys(o)、Object.values(o)、Object.entries(o) 來取得表示鍵或值的數(shù)字)迭代時(shí)的順序就是上面提到的順序。

      const o = {};  const m = new Map();  o[Symbol.iterator] !== undefined; // false  m[Symbol.iterator] !== undefined; // true

      在 Map 中新增鍵時(shí),不會覆蓋其原型上的鍵;而在 Object 中新增鍵時(shí),則有可能覆蓋其原型上的鍵:

      Object.prototype.x = 1;    const o = {x:2};    const m = new Map([[x,2]]);    o.x; // 2,x = 1 被覆蓋了    m.x; // 1,x = 1 不會被覆蓋

      JSON 默認(rèn)支持 Object 而不支持 Map。若想要通過 JSON 傳輸 Map 則需要使用到 .toJSON() 方法,然后在 JSON.parse() 中傳入復(fù)原函數(shù)來將其復(fù)原。

      對于 JSON 這里就不具體展開了,有興趣的朋友可以看一下這:JSON 的序列化和解析

      const o = {x:1};    const m = new Map([['x', 1]]);    const o2 = JSON.parse(JSON.stringify(o)); // {x:1}    const m2 = JSON.parse(JSON.stringify(m)) // {}

      句法對比

      創(chuàng)建時(shí)的區(qū)別

      Obejct

      const o = {}; // 對象字面量  const o = new Object(); // 調(diào)用構(gòu)造函數(shù)  const o = Object.create(null); // 調(diào)用靜態(tài)方法 Object.create

      對于 Object 來說,我們在 95%+ 的情況下都會選擇對象字面量,它不僅寫起來最簡單,而且相較于下面的函數(shù)調(diào)用,在性能方面會更為高效。對于構(gòu)建函數(shù),可能唯一使用到的情況就是顯式的封裝一個基本類型;而 Object.create 可以為對象設(shè)定原型。

      Map

      const m = new Map(); // 調(diào)用構(gòu)造函數(shù)  和 Object 不同,Map 沒有那么多花里胡哨的創(chuàng)建方法,通常只會使用其構(gòu)造函數(shù)來創(chuàng)建。

      除了上述方法之外,我們也可以通過 Function.prototype.apply()、Function.prototype.call()、reflect.apply()、Reflect.construct() 方法來調(diào)用 Object 和 Map 的構(gòu)造函數(shù)或者  Object.create() 方法,這里就不展開了。

      新增/讀取/刪除元素時(shí)的區(qū)別

      Obejct

      const o = {};  //新增/修改  o.x = 1;  o['y'] = 2;  //讀取  o.x; // 1  o['y']; // 2  //或者使用 ES2020 新增的條件屬性訪問表達(dá)式來讀取  o?.x; // 1  o?.['y']; // 2  //刪除  delete o.b;

      對于新增元素,看似使用第一種方法更為簡單,不過它也有些許限制:

      屬性名不能包含空格和標(biāo)點(diǎn)符號

      屬性名不能以數(shù)字開頭

      對于條件屬性訪問表達(dá)式的更多內(nèi)容可以看一下這:條件屬性訪問表達(dá)式

      Map

      const m = new Map();  //新增/修改  m.set('x', 1);  //讀取  map.get('x');  //刪除  map.delete('b');

      對于簡單的增刪查改來說,Map 上的方法使用起來也是十分便捷的;不過在進(jìn)行聯(lián)動操作時(shí),Map 中的用法則會略顯臃腫:

      const m = new Map([['x',1]]);  // 若想要將 x 的值在原有基礎(chǔ)上加一,我們需要這么做:  m.set('x', m.get('x') + 1);  m.get('x'); // 2  const o = {x: 1};  // 在對象上修改則會簡單許多:  o.x++;  o.x // 2

      性能對比

      接下來我們來討論一下 Object 和 Map 的性能。不知道各位有沒有聽說過 Map 的性能優(yōu)于 Object 的說法,我反正是見過不少次,甚至在 JS 高程四中也提到了 Map 對比 Object 時(shí)性能的優(yōu)勢;不過對于性能的概括都十分的籠統(tǒng),所以我打算做一些測試來對比一下它們的區(qū)別。

      測試方法

      在這里我進(jìn)行的對于性能測試的都是基于 v8 引擎的。速度會通過 JS 標(biāo)準(zhǔn)庫自帶的 performance.now() 函數(shù)來判斷,內(nèi)存使用情況會通過 Chrome devtool 中的 memory 來查看。

      對于速度測試,因?yàn)閱我坏牟僮魉俣忍炝耍芏鄷r(shí)候 performance.now() 會返回 0。所以我進(jìn)行了 10000 次的循環(huán)然后判斷時(shí)間差。因?yàn)檠h(huán)本身也會占據(jù)一部分時(shí)間,所以以下的測試只能作為一個大致的參考。

      創(chuàng)建時(shí)的性能

      測試用的代碼如下:

      let n,  n2 = 5;  // 速度  while (n2--) {    let p1 = performance.now();    n = 10000;    while (n--) { let o = {}; }    let p2 = performance.now();    n = 10000;    while (n--) { let m = new Map(); }    let p3 = performance.now();    console.log(`Object: ${(p2 - p1).toFixed(3)}ms, Map: ${(p3 - p2).toFixed(3)}ms`);  }  // 內(nèi)存  class Test {}  let test = new Test();  test.o = o;  test.m = m;

      首先進(jìn)行對比的是創(chuàng)建 Object 和 Map 時(shí)的表現(xiàn)。對于創(chuàng)建的速度表現(xiàn)如下:

      JavaScript中Object和Map有哪些區(qū)別

      我們可以發(fā)現(xiàn)創(chuàng)建 Object 的速度會快于 Map。對于內(nèi)存使用情況則如下:

      JavaScript中Object和Map有哪些區(qū)別

      我們主要關(guān)注其 Retained Size,它表示了為其分配的空間。(即刪除時(shí)釋放的內(nèi)存大小)

      通過對比我們可以發(fā)現(xiàn),空的 Object 會比空的 Map 占用更少的內(nèi)。所以這一輪 Object 贏得一籌。

      新增元素時(shí)的性能

      測試用的代碼如下:

      console.clear();  let n,  n2 = 5;  let o = {}, m = new Map();  // 速度  while (n2--) {    let p1 = performance.now();    n = 10000;    while (n--) { o[Math.random()] = Math.random(); }    let p2 = performance.now();    n = 10000;    while (n--) { m.set(Math.random(), Math.random()); }    let p3 = performance.now();    console.log(`Object: ${(p2 - p1).toFixed(3)}ms, Map: ${(p3 - p2).toFixed(3)}ms`);  }  // 內(nèi)存  class Test {}  let test = new Test();  test.o = o;  test.m = m;

      對于新建元素時(shí)的速度表現(xiàn)如下:

      JavaScript中Object和Map有哪些區(qū)別

      我們可以發(fā)現(xiàn)新建元素時(shí),Map 的速度會快于 Object。對于內(nèi)存使用情況則如下:

      JavaScript中Object和Map有哪些區(qū)別

      通過對比我們可以發(fā)現(xiàn),在擁有一定數(shù)量的元素時(shí), Object 會比 Map 占用多了約 78% 的內(nèi)存。我也進(jìn)行了多次的測試,發(fā)現(xiàn)在擁有足夠的元素時(shí),這個百分比是十分穩(wěn)定的。所以說,在需要進(jìn)行很多新增操作,且需要儲存許多數(shù)據(jù)的時(shí)候,使用 Map 會更高效。

      讀取元素時(shí)的性能

      測試用的代碼如下:

      let n;  let o = {}, m = new Map();  n = 10000;  while (n--) { o[Math.random()] = Math.random(); }  n = 10000; while (n--) { m.set(Math.random(), Math.random()); }  let p1 = performance.now();  for (key in o) { let k = o[key]; }  let p2 = performance.now();  for ([key] of m) { let k = m.get(key); }  let p3 = performance.now();  `Object: ${(p2 - p1).toFixed(3)}ms, Map: ${(p3 - p2).toFixed(3)}ms`

      對于讀取元素時(shí)的速度表現(xiàn)如下:

      JavaScript中Object和Map有哪些區(qū)別

      通過對比,我們可以發(fā)現(xiàn) Object 略占優(yōu)勢,但總體差別不大。

      刪除元素時(shí)的性能

      不知道大家是否聽說過 delete 操作符性能低下,甚至有很多時(shí)候?yàn)榱诵阅埽瑫幙蓪⒅翟O(shè)置為 undefined 而不使用 delete 操作符的說法。但其實(shí)在 v8 近來的優(yōu)化下,它的效率已經(jīng)提升許多了。

      測試用的代碼如下:

      let n;  let o = {}, m = new Map();  n = 10000;  while (n--) { o[Math.random()] = Math.random(); }  n = 10000;  while (n--) { m.set(Math.random(), Math.random()); }  let p1 = performance.now();  for (key in o) { delete o[key]; }  let p2 = performance.now();  for ([key] of m) { m.delete(key); }  let p3 = performance.now();  `Object: ${(p2 - p1).toFixed(3)}ms, Map: ${(p3 - p2).toFixed(3)}ms`

      對于刪除元素時(shí)的速度表現(xiàn)如下:

      JavaScript中Object和Map有哪些區(qū)別

      我們可以發(fā)現(xiàn)在進(jìn)行刪除操作時(shí),Map 的速度會略占優(yōu),但整體差別其實(shí)并不大。

      特殊情況

      其實(shí)除了最基本的情況之外,還有一種特殊的情況。還記得我們在前面提到的 Object 中鍵的排序嗎?我們提到了其中的非負(fù)整數(shù)會被最先列出。其實(shí)對于非負(fù)整數(shù)作為鍵的值和其余類型作為鍵的值來說,v8 是會對它們進(jìn)行區(qū)別對待的。負(fù)整數(shù)作為鍵的部分會被當(dāng)成數(shù)組對待,即非負(fù)整數(shù)具有一定的連續(xù)性時(shí),會被當(dāng)成快數(shù)組,而過于稀疏時(shí)會被當(dāng)成慢數(shù)組。

      對于快數(shù)組,它擁有連續(xù)的內(nèi)存,所以在進(jìn)行讀寫時(shí)會更快,且占用更少的內(nèi)存。更多的內(nèi)容可以看一下這: 探究JS V8引擎下的“數(shù)組”底層實(shí)現(xiàn)

      在鍵為連續(xù)非負(fù)整數(shù)時(shí),性能如下:

      JavaScript中Object和Map有哪些區(qū)別

      JavaScript中Object和Map有哪些區(qū)別

      我們可以看到 Object 不僅平均速度更快了,其占用的內(nèi)存也大大減少了。

      感謝各位的閱讀,以上就是“JavaScript中Object和Map有哪些區(qū)別”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對JavaScript中Object和Map有哪些區(qū)別這一問題有了更深刻的體會,具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識點(diǎn)的文章,歡迎關(guān)注!


      當(dāng)前文章:JavaScript中Object和Map有哪些區(qū)別
      URL地址:http://www.ef60e0e.cn/article/jhiecj.html
      99热在线精品一区二区三区_国产伦精品一区二区三区女破破_亚洲一区二区三区无码_精品国产欧美日韩另类一区
      1. <ul id="0c1fb"></ul>

        <noscript id="0c1fb"><video id="0c1fb"></video></noscript>
        <noscript id="0c1fb"><listing id="0c1fb"><thead id="0c1fb"></thead></listing></noscript>

        辽宁省| 文昌市| 甘洛县| 三门县| 徐汇区| 三穗县| 成武县| 合作市| 苍山县| 鹿泉市| 金湖县| 徐汇区| 达孜县| 汕头市| 翁牛特旗| 大宁县| 淳安县| 房产| 宁远县| 民权县| 吕梁市| 蒙自县| 中江县| 南华县| 永靖县| 新昌县| 崇明县| 千阳县| 夏津县| 梧州市| 互助| 石狮市| 南溪县| 灌云县| 平顶山市| 安达市| 江阴市| 原阳县| 松原市| 江门市| 札达县|