1. 程式人生 > >js:變量,作用域以及內存問題

js:變量,作用域以及內存問題

arr 循環 引用類型 表示 推出 基本 改變 機制 定義

最近在重讀《javascript高級程序設計》這本書,“溫故而知新”,古人誠不欺我,再看的時候發現很多知識是之前不理解便跳過的,也有很多之前只是知道並記住了,並不能形成一套體系,而不斷的回顧,不斷地總結,我發現有很多零零散散的知識點在不經意間就被串在了一起,恍然大悟的感覺甚是美妙

而我一向喜歡思維導圖和記憶的方式去學習總結,在用文字表達和總結方面顯得很貧乏,所以打算用這種博客的形式來記錄下重讀過程中的總結,就當是記個筆記,也順便練練表達能力

變量:

js中的變量可能包含兩種不同數據類型的值:分為基本類型值和引用類型值。兩者區分的本質是取決於變量在內存中的存儲方式,基本類型值存放在棧內存中,引用類型值保存在堆內存中。

而由於兩種類型的保存方式不同,我們在復制變量值的時候就會發現:對基本類型值的復制是值復制,復制後的變量值與變量值只是數據相同而且,在內存中是獨立的;對引用類型值的復制是其實也是“值”復制,不過這個值是一個指針,而我們真正會操作的數據是指針指向的一個內存,我們復制的那個指針“值”只是一個指向真正數據內存的地址,也就是我們常說的引用,所以,在引用類型的復制中,最終復制後的變量與復制前的變量指向同一數據,所以對其中任何一個變量進行改變都會影響另外一個

目前簡單數據類型有:Undefined,Null,String,Number,Boolean,Symbol(es6新增數據類型)

復雜數據類型:Object

而對簡單數據類型,通常用typeof來判斷,其返回值有:“undefined”,“string”,“number”,“boolean”,“symbol”,“function”,“object”而typeof null == “object”,是因為歷史遺留問題,而本身null也表示“該變量為一個空的指針”,所以,其typeof的結果為“object”也可以理解了

而對復雜數據類型,通常使用instanceof來判斷,表示是否是該對象的實例對象,通過原型鏈(暫不做討論)來判斷

而對一些特殊的數據類型,我們也有對應的方法判斷其類型:數據的Array.isArray,非數字的isNaN

執行環境與作用域:

首先,明確幾個知識點:1)每個函數都有自己的執行環境 2)執行環境定義了變量或函數有權訪問的其他數據 3)每個執行環境都有一個與之關聯的變量對象,執行環境中定義的所有變量和函數都保存在這個對象中

對以上三點我所理解的就是:每個函數在內存中都有一個與之關聯的對象,該對象中保存了這個函數內部定義的變量,方法等一切信息,是對這個函數的一個描述對象

而當函數執行時,函數的執行環境會被推入到一個環境棧中,此時會形成與其他執行環境的一種“包含”或者“平行”的關系,而這種“包含”的體現就是“作用域鏈”,更嚴謹的說法是:當代碼再一個環境中執行時,會創建變量對象的一個作用域鏈。而作用域鏈的作用就很牛逼了,我們經常說的變量查找從局部作用域到外層再到外層直至全局作用域就是依靠這條作用域鏈。作用域鏈只能向上查找。

內存問題

js的垃圾回收機制使得執行環境會管理代碼執行過程中使用的內存,而按照我們對執行環境和作用域的理解,我們知道,代碼執行結束後,執行環境被從環境棧中推出,此時執行環境中的局部變量也就沒有存在的意義了,所以,此時需要告知該執行環境中的局部變量應該被回收,而具體的回收策略在瀏覽器中有:

1:標記清除:變量的標記從“進入執行環境”到“離開執行環境”,回收機制只要清除那些標有“離開”的變量即可

2:引用計數:當聲明了一個變量並將一個引用類型值賦給該變量時,則這個值的引用次數加1,如果同一個值又被賦給另外一個變量,則減1,回收機制負責回收引用次數為0的值。但是這種方法遇到循環引用時,便會陷入僵局,所以,該方法使用場景較少

越寫越亂的感覺,表達能力還是太欠缺了,還需要多練習,對知識也要深入理解,加油!!!

js:變量,作用域以及內存問題