成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

淺析JS中的堆內存與棧內存

Faremax / 464人閱讀

摘要:如,不是定義常量么為什么還能改這就是我們今天要說的重點中的堆內存與棧內存在引擎中對變量的存儲主要有兩種位置,堆內存和棧內存。而堆內存首先要在堆內存新分配存儲區(qū)域,之后又要把指針存儲到棧內存中,效率相對就要低一些了。

最近跟著組里的大佬面試碰到這么一個問題,

Q:說說var、let、const的區(qū)別
A:balabalabalabla...
Q:const定義的值能改么?
A:你逗我?不能吧

不知道各位看官怎么想?答案是部分能改,部分不能改。const定義的基本類型不能改變,但是定義的對象是可以通過修改對象屬性等方法來改變的。如,

>>> const a = 1
>>> a
<<< 1
>>> a = 2
<<< VM1750:1 Uncaught TypeError: Assignment to constant variable.
    at :1:3
    (anonymous) @ VM1750:1
>>> const b = {}
>>> b
<<< {}
>>> b.name = 1
>>> b
<<< {name: 1}
>>> b = {}
<<< VM1785:1 Uncaught TypeError: Assignment to constant variable.
    at :1:4

const不是定義常量么?為什么還能改?這就是我們今天要說的重點~

js中的堆內存與棧內存

在js引擎中對變量的存儲主要有兩種位置,堆內存和棧內存。

和java中對內存的處理類似,棧內存主要用于存儲各種基本類型的變量,包括Boolean、Number、String、Undefined、Null,**以及對象變量的指針,這時候棧內存給人的感覺就像一個線性排列的空間,每個小單元大小基本相等。

而堆內存主要負責像對象Object這種變量類型的存儲,如下圖

棧內存中的變量一般都是已知大小或者有范圍上限的,算作一種簡單存儲。而堆內存存儲的對象類型數(shù)據(jù)對于大小這方面,一般都是未知的。個人認為,這也是為什么null作為一個object類型的變量卻存儲在棧內存中的原因。

因此當我們定義一個const對象的時候,我們說的常量其實是指針,就是const對象對應的堆內存指向是不變的,但是堆內存中的數(shù)據(jù)本身的大小或者屬性是可變的。而對于const定義的基礎變量而言,這個值就相當于const對象的指針,是不可變。

既然知道了const在內存中的存儲,那么const、let定義的變量不能二次定義的流程也就比較容易猜出來了,每次使用const或者let去初始化一個變量的時候,會首先遍歷當前的內存棧,看看有沒有重名變量,有的話就返回錯誤。

說到這里,有一個十分很容易忽略的點,之前也是自己一直沒有注意的就是,使用new關鍵字初始化的之后是不存儲在棧內存中的。為什么呢?new大家都知道,根據(jù)構造函數(shù)生成新實例,這個時候生成的是對象,而不是基本類型。再看一個例子

var a = new String("123")
var b = String("123")
var c = "123"
console.log(a==b, a===b, b==c, b===c, a==c, a===c)    
>>> true false true true true false
console.log(typeof a)
>>> "object"

我們可以看到new一個String,出來的是對象,而直接字面量賦值和工廠模式出來的都是字符串。但是根據(jù)我們上面的分析大小相對固定可預期的即便是對象也可以存儲在棧內存的,比如null,為啥這個不是呢?再繼續(xù)看

var a = new String("123")
var b = new String("123")
console.log(a==b, a===b)
>>> false false

很明顯,如果a,b是存儲在棧內存中的話,兩者應該是明顯相等的,就像null === null是true一樣,但結果兩者并不相等,說明兩者都是存儲在堆內存中的,指針指向不一致。

說到這里,再去想一想我們常說的值類型和引用類型其實說的就是棧內存變量和堆內存變量,再想想值傳遞和引用傳遞、深拷貝和淺拷貝,都是圍繞堆棧內存展開的,一個是處理值,一個是處理指針。

內存分配和垃圾回收

一般來說棧內存線性有序存儲,容量小,系統(tǒng)分配效率高。而堆內存首先要在堆內存新分配存儲區(qū)域,之后又要把指針存儲到棧內存中,效率相對就要低一些了。
垃圾回收方面,棧內存變量基本上用完就回收了,而推內存中的變量因為存在很多不確定的引用,只有當所有調用的變量全部銷毀之后才能回收。

繼續(xù)往下思考的話,其中還有很多的東西需要去學習,今天先到這里,后續(xù)再來補充。

話說~NaN會不會也是存儲在堆內存中的呢?大家想想吧,歡迎大家來一起討論討論~文中如有錯誤歡迎指出~

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉載請注明本文地址:http://systransis.cn/yun/96984.html

相關文章

  • 與棧

    摘要:堆與棧棧由編譯器自動分配存放函數(shù)的參數(shù)值局部變量的值等其操作方式類似于數(shù)據(jù)結構中的棧堆一般由程序員分配釋放若程序員不釋放程序結束時可能由回收這里是指操作系統(tǒng)區(qū)別和聯(lián)系申請方式堆由程序員自己申請并指明大小在語言中的函數(shù)棧由系統(tǒng)自動分配聲明在函 堆與棧 棧(stack): 由編譯器自動分配, 存放函數(shù)的參數(shù)值, 局部變量的值等. 其操作方式類似于數(shù)據(jù)結構中的棧. 堆(heap): 一般由...

    April 評論0 收藏0
  • 【V8引擎】淺析Chrome V8引擎中的垃圾回收機制和內存泄露優(yōu)化策略

    摘要:一前言的垃圾回收機制使用垃圾回收機制來自動管理內存。垃圾回收器只會針對新生代內存區(qū)老生代指針區(qū)以及老生代數(shù)據(jù)區(qū)進行垃圾回收。分別對新生代和老生代使用不同的垃圾回收算法來提升垃圾回收的效率。 V8 實現(xiàn)了準確式 GC,GC 算法采用了分代式垃圾回收機制。因此,V8 將內存(堆)分為新生代和老生代兩部分。 一、前言 V8的垃圾回收機制:JavaScript使用垃圾回收機制來自動管理內存。垃...

    qingshanli1988 評論0 收藏0
  • js中深拷貝與淺拷貝(堆內存、棧內存的關系)

    摘要:而堆內存主要負責像對象這種變量類型的存儲,如下圖引用類型中復制淺拷貝的只是棧內存中的指針,指向同一個堆內存的對象如何實現(xiàn)深拷貝最簡單的方法就是與方法 淺拷貝只會在引用類型中出現(xiàn) 基本數(shù)據(jù)類型有哪些,number,string,boolean,null,undefined,symbol以及未來ES10新增的BigInt(任意精度整數(shù))七類。 引用數(shù)據(jù)類型(Object類)有常規(guī)名值對的無...

    AlienZHOU 評論0 收藏0
  • JS數(shù)據(jù)類型 與 內存堆棧

    摘要:所以相對于簡單數(shù)據(jù)類型而言,他們占用內存比較小,如果放在堆中,查找會浪費很多時間,而把堆中的數(shù)據(jù)放入棧中也會影響棧的效率。六總結本文總結了數(shù)據(jù)類型及其聲明賦值更新時在內存堆棧中的表現(xiàn),可以更深入的理解這些數(shù)據(jù)類型。 JS數(shù)據(jù)類型 與 內存堆棧 一、前言 JS的數(shù)據(jù)類型已經是大家都很熟悉的東西了,但是大家是否對這些數(shù)據(jù)類型在內存中的分配了解,甚至在操作這些變量時,內存中是如何表現(xiàn)的,本文...

    nodejh 評論0 收藏0
  • js堆,棧與隊列

    摘要:內存空間又被分為兩種,棧內存與堆內存。今天就堆棧隊列的內容就大概說到這里下一篇博客在繼續(xù)說一下,有什么說的不對或者不足的地方,請大家批評指正 棧的定義 棧是計算機科學中的一種抽象數(shù)據(jù)類型,只允許在有序的線性數(shù)據(jù)集合的一端(稱為堆棧頂端,英語:top)進行加入數(shù)據(jù)(英語:push)和移除數(shù)據(jù)(英語:pop)的運算。因而按照后進先出(LIFO, Last In First Out)的原理運...

    Kosmos 評論0 收藏0

發(fā)表評論

0條評論

Faremax

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<