淺談javaScript記憶體

来源:https://www.cnblogs.com/soldoros/archive/2018/05/17/9050004.html
-Advertisement-
Play Games

一 背景 var a = 20; var b = 'abc'; var c = true; var d = { m: 20 } 因為JavaScript具有自動垃圾回收機制,所以對於前端開發來說,記憶體空間並不是一個經常被提及的概念,很容易被大家忽視。特別是很多不是電腦專業的朋友在進入到前端之後,會 ...


一 背景

 

var a = 20;

var b = 'abc';

var c = true;

var d = { m: 20 }

 

因為JavaScript具有自動垃圾回收機制,所以對於前端開發來說,記憶體空間並不是一個經常被提及的概念,很容易被大家忽視。特別是很多不是電腦專業的朋友在進入到前端之後,會對記憶體空間的認知比較模糊,甚至有些人乾脆就是一無所知.

 

當然也包括我自己。在很長一段時間里認為記憶體空間的概念在JS的學習中並不是那麼重要。可是後我當我回過頭來重新整理JS基礎時,發現由於對它們的模糊認知,導致了很多東西我都理解得並不明白。比如最基本的引用數據類型和引用傳遞到底是怎麼回事兒?比如淺複製與深複製有什麼不同?還有閉包,原型等等.

 

因此後來我才漸漸明白,想要對JS的理解更加深刻,就必須對記憶體空間有一個清晰的認知.

二 棧與堆

與c++類似,javaScipt中的記憶體也分為棧區和堆區,它們存儲數據的機制不同,導致存儲數據的類型也不同,棧區主要存儲簡單數據類型,堆區主要存儲引用數據類型.

 

首先我們簡單瞭解下棧的存取方式,這裡我們可以通過類比乒乓球盒子來分析。如下圖

這種乒乓球的存放方式與棧中存取數據的方式如出一轍。處於盒子中最頂層的乒乓球5,它一定是最後被放進去,但可以最先被使用。而我們想要使用底層的乒乓球1,就必須將上面的4個乒乓球取出來,讓乒乓球1處於盒子頂層。這就是棧空間先進後出,後進先出的特點。圖中已經詳細的表明瞭棧空間的存儲原理。

 

堆存取數據的方式,則與書架與書非常相似。書雖然也整齊的存放在書架上,但是我們只要知道書的名字,我們就可以很方便的取出我們想要的書,而不用像從乒乓球盒子里取乒乓一樣,非得將上面的所有乒乓球拿出來才能取到中間的某一個乒乓球。好比在JSON格式的數據中,我們存儲的key-value是可以無序的,因為順序的不同並不影響我們的使用,我們只需要關心書的名字。

 

三 複雜數據類型與基本數據類型

基礎數據類型都是一些簡單的數據段,JavaScript中有5中基礎數據類型,分別是Undefined、Null、Boolean、Number、String。基礎數據類型都是按值訪問,因為我們可以直接操作保存在變數中的實際的值。複雜數據類型 包括數組,對象等.

 

四 引用數據類型與堆記憶體

與其他語言不同,JS的引用數據類型,比如數組Array,它們值的大小是不固定的。引用數據類型的值是保存在堆記憶體中的對象。JavaScript不允許直接訪問堆記憶體中的位置,因此我們不能直接操作對象的堆記憶體空間。在操作對象時,實際上是在操作對象的引用而不是實際的對象。因此,引用類型的值都是按引用訪問的。這裡的引用,我們可以粗淺地理解為保存在變數對象中的一個地址,該地址與堆記憶體的實際值相關聯。

 

為了更好的搞懂變數對象與堆記憶體,我們可以結合以下例子與圖解進行理解.

var b = { m: 20 }; // 變數b存在棧中,對應的值就是一個索引指向對象{m: 20},{m:20}作為對象存在於堆記憶體中.

 

因此當我們要訪問堆記憶體中的引用數據類型時,實際上我們首先是從變數對象中獲取了該對象的地址引用(或者地址指針),然後再從堆記憶體中取得我們需要的數據。

理解了JS的記憶體空間,我們就可以藉助記憶體空間的特性來驗證一下引用類型的一些特點了。

 

在前端面試中我們常常會遇到這樣一個類似的題目

// demo01.js

var a = 20;

var b = a;

b = 30;

 

// 這時a的值是多少?

 

// demo02.js

var m = { a: 10, b: 20 }

var n = m;

n.a = 15;

 

// 這時m.a的值是多少

在變數對象中的數據發生複製行為時,系統會自動為新的變數分配一個新值。var b = a執行之後,a與b雖然值都等於20,但是他們其實已經是相互獨立互不影響的值了。具體如圖。所以我們修改了b的值以後,a的值並不會發生變化。

 

                            demo01圖解

 

在demo02中,我們通過var n = m執行一次複製引用類型的操作。引用類型的複製同樣也會為新的變數自動分配一個新的值保存在變數對象中,但不同的是,這個新的值,僅僅只是引用類型的一個地址指針。當地址指針相同時,儘管他們相互獨立,但是在變數對象中訪問到的具體對象實際上是同一個。如圖所示

因此當我改變n時,m也發生了變化。這就是引用類型的特性。

 

通過記憶體的角度來理解,是不是感覺要輕鬆很多。除此之外,我們還可以以此為基礎,一步一步的理解JavaScript的執行上下文,作用域鏈,閉包,原型鏈等重要概念。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 今天才知道原來position加上上下左右可以控制的到div的寬度的 比如我現在有一個需要 這樣一個需求 現在是紅色部分50px 但是你可能不知道剩下的藍色部分的高度是多少 藍色部分要怎麼填滿剩餘的高度呢 這時候left,right,top,bottom,就很有用了 直接給藍色的div:positi ...
  • 前言: 最近剛剛完成項目,空閑一段時間,想起之前有被問起怎麼對前端進行性能優化,自己也是腦中零零散散的總不成體系,現特來總結,歡迎補充指教。 1、整體資源 (1)js、css源碼壓縮 (2)css文件放到文檔頂部,js 文件放到文檔底部 因為瀏覽器渲染網頁是自上而下的,用戶第一眼見到的是頁面,先載入 ...
  • scoped css "官方文檔" scoped css可以直接在能跑起來的vue項目中使用。 使用方法: 使用scoped劃分本地樣式的結果編譯結果如下: 即在元素中添加了一個唯一屬性用來區分。 缺點 一、如果用戶在別處定義了相同的類名,也許還是會影響到組件的樣式。 二、根據css樣式優先順序的特性 ...
  • 一、 redux出現的動機 1. Javascript 需要管理比任何時候都要多的state2. state 在什麼時候,由於什麼原因,如何變化已然不受控制。3. 來自前端開發領域的新需求4. 我們總是將兩個難以理清的概念混淆在一起:變化和非同步。5. Redux 視圖讓state 的變化變得可預測。 ...
  • 1.非同步 程式中現在運行的部分和將來運行的部分之間的關係是非同步編程的核心。 多數JavaScript開發者從來沒有認真思考過自己程式中的非同步到底是如何出現的,以及為什麼會出現,也沒有探索過處理非同步的其他方法。一直以來,低調的回調函數就算足夠好的方法了。目前為止,還有很多人堅持認為回調函數完全夠用。 ...
  • 大型Web應用對速度的追求並沒有止步於僅僅利用瀏覽器緩存,因為瀏覽器緩存始終只是為了提升二次訪問的速度,對於首次訪問的加速,我們需要從網路層面進行優化,最常見的手段就是CDN(Content Delivery Network,內容分髮網絡)加速。通過將靜態資源緩存到離用戶很近的相同網路運營商的CDN ...
  • 前言 移動端開發,經常會遇到的問題,就是文字居中。一般都只能往css方向去fix這個問題。 自己以前也用過 的方式去解決。
  • 1 <script src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.js"></script> 2 <script> 3 //json擴展方法 4 if (!Object.prototype.forEach) { 5 Object.protot ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...