JavaScript的環境與記憶體
使用具備垃圾收集機制語言編寫程式,開發人員一般不必操心記憶體管理的問題。但是,JavaScript在進行記憶體管理即垃圾收集時面臨的問題還是有點與眾不同。其中最主要的一個問題,就是分配給Web瀏覽器的可用記憶體數量通常要比分配給桌面應用程式的少。確保佔有最少的記憶體可以讓頁面獲得更好的效能,而優化記憶體佔有最佳方式,就是為執行的程式碼值儲存必要的資料。
基本型別值和引用型別值
ECMAScript變數包含兩種不同資料型別的值:基本型別值和引用型別值。基本型別值儲存在棧記憶體中,而引用型別值儲存在堆記憶體中。
5種基本型別Undefined、Null、Boolean、Number、String,它們的值在記憶體中分別佔有固定大小的空間,因此可以把它們的值儲存在棧記憶體中,也可以提高查詢變數的速度,對於它們可以說是按值訪問的。 如果是引用型別的值,則必須在堆記憶體中分配空間。因為它們的值大小不固定,因此不能儲存在棧記憶體中,但記憶體地址的大小是固定的,所以可以將記憶體地址儲存在棧記憶體中,再根據地址找到儲存在堆中的值,這種查詢方式叫做按引用訪問。
動態屬性
對於引用型別的值,可以為其新增屬性和方法,也可以改變和刪除其屬性和方法,例如:
var myobj = new Object();
myobj.name = "obj";
alert(myobj.name);
但是不能給基本型別的值新增屬性,例如:
var mystr = "string";
mystr.name = "str";
alert(mystr.name); //undefined
複製變數值
如果從一個變數向另一個變數複製基本型別的值,會在棧中建立一個新值,然後把該值複製到為新變數分配的位置上,例如:
var num1 = 5;
var num2 = num1;
如果從一個變數向另一個變數複製引用型別的值,同樣會將儲存在棧中的值複製一份放到為新變數分配的空間中。但是這個值的副本實際是指向儲存在堆中的一個物件的指標,例如:
var myobj1 = new Object();
var myobj2 = myobj1;
myobj1.name = "obj";
alert(myobj2.name); //obj
傳遞引數
ECMAScript中所有函式引數都是按值傳遞的。在向引數傳遞基本型別的值時,被傳遞的值會被複制給一個區域性變數,在向引數傳遞引用型別的值時,會把這個值在記憶體中的地址複製給一個區域性變數。
使用基本型別值傳遞引數比較簡單,例如:
function add(num) {
num += 10;
return num;
}
var number = 20;
var result = add(number);
alert(number); //20
alert(result); //30
如果使用引用型別值則稍複雜,例如:
function setName(obj) {
obj.name = "obj";
}
var myobj = new Object();
setName(myobj);
alert(myobj.name); //obj
但這並不表明區域性作用域中修改的物件會在全域性作用域中反映出來,物件仍然是按值(記憶體地址)傳遞的,例如:
function setName(obj) {
obj.name = "obj";
obj = new Object();
obj.name = "new obj";
}
var myobj = new Object();
setName(myobj);
alert(myobj.name); //obj
檢測型別
typeof操作符可以檢測一個變數是哪種基本型別,但在檢測引用型別時,總是返回object。通常我們並不是想知道某個值是物件,而是想知道它是什麼型別的物件,可以使用instanceof操作符,語法如下:
result = variable instanceof constructor
如果變數是給定引用型別的例項,那麼instanceof操作符就會返回true。根據規定,所有引用型別的值都是Object的例項。
環境與作用域
執行環境定義了變數或函式有權訪問的其他資料,每個執行環境都有一個與之關聯的變數物件,環境中定義的所有變數和函式都儲存在這個物件中。這個物件無法訪問,但解析器會在後臺使用它。全域性執行環境是最外圍的一個執行環境,在Web瀏覽器中,全域性執行環境被認為是window物件。某個執行環境中的所有程式碼執行完畢後,該環境被銷燬,儲存在其中的所有變數和函式定義也隨之銷燬。
當程式碼在一個環境中執行時,會建立由變數物件構成的一個作用域鏈,保證對執行環境有權訪問的所有變數和函式的有序訪問。全域性執行環境是作用域鏈中的最後一環,識別符號解析是沿著作用域鏈一級級搜尋,從作用域連結前端(當前執行環境)開始,直到找到識別符號為止。
作用域鏈的延長
有些語句可以在作用域鏈的前端臨時增加一個變數物件,該變數物件會在程式碼執行後被移除,即當執行流進入下列任何一個語句時,作用域鏈就會得到加長:
try-cache語句的catch塊。 with語句。
塊級作用域
JavaScript沒有塊級作用域,即花括號封閉的程式碼塊中定義的變數可以在程式碼塊外訪問,例如:
if (true) {
var color = "blue";
}
alert(color);
變數宣告
在使用var關鍵字宣告變數時,這個變數將被自動新增到距離最近的可用環境中。如果變數在未經宣告的情況下被初始化,那麼該變數會被自動新增到全域性環境。
本文為Anyforweb技術分享部落格,需要了解網站建設及更多Web應用相關資訊,請訪問anyforweb.com。
相關文章
- HP-UX環境下檢視記憶體UX記憶體
- Fedora 上的桌面環境記憶體佔用測試記憶體
- JavaScript的記憶體管理JavaScript記憶體
- 深入JavaScript系列(五):JS與記憶體JavaScriptJS記憶體
- JavaScript 記憶體管理JavaScript記憶體
- JavaScript記憶體分配JavaScript記憶體
- JavaScript記憶體管理JavaScript記憶體
- 【譯】JavaScript 的記憶體模型JavaScript記憶體模型
- javascript中的記憶體管理JavaScript記憶體
- JavaScript對記憶體的使用JavaScript記憶體
- K8S(18)容器環境下資源限制與jvm記憶體回收K8SJVM記憶體
- 生產環境Java應用服務記憶體洩漏分析與解決Java記憶體
- 如何避免JavaScript的記憶體洩露及記憶體管理技巧JavaScript記憶體洩露
- JavaScript 是如何工作的:JavaScript 的記憶體模型JavaScript記憶體模型
- JavaScript 記憶體機制JavaScript記憶體
- JavaScript記憶體洩露JavaScript記憶體洩露
- Javascript記憶體洩漏JavaScript記憶體
- Go:記憶體管理與記憶體清理Go記憶體
- 聊聊 記憶體模型與記憶體序記憶體模型
- JavaScript之記憶體溢位和記憶體洩漏JavaScript記憶體溢位
- Metasploit執行環境記憶體不要低於2GB記憶體
- 記憶體的分配與釋放,記憶體洩漏記憶體
- 超大記憶體環境下的Oracle RAC引數設定建議記憶體Oracle
- javascript的記憶體管理以及3種常見的記憶體洩漏JavaScript記憶體
- 記憶體分析與記憶體洩漏定位記憶體
- 關於JavaScript的記憶體機制JavaScript記憶體
- JavaScript中的記憶體洩露模式JavaScript記憶體洩露模式
- JavaScript之記憶體空間JavaScript記憶體
- javaScript 記憶體管理機制JavaScript記憶體
- JavaScript 記憶體洩漏教程JavaScript記憶體
- 主備庫記憶體不一致的Data Guard環境搭建記憶體
- JVM——記憶體洩漏與記憶體溢位JVM記憶體溢位
- [轉載] Java直接記憶體與堆記憶體Java記憶體
- 【譯】JavaScript的記憶體管理和 4 種處理記憶體洩漏的方法JavaScript記憶體
- ArkTS 的記憶體快照與記憶體洩露除錯記憶體洩露除錯
- 【記憶體洩漏和記憶體溢位】JavaScript之深入淺出理解記憶體洩漏和記憶體溢位記憶體溢位JavaScript
- JavaScript執行環境與執行棧JavaScript
- X86環境大記憶體下資料庫啟動問題分析與處理記憶體資料庫