摘要:在中雖然對象通過標記清除的方式進行垃圾收,但與對象卻是通過引用計數回收垃圾的,也就是說只要涉及及就會出現循環引用問題。如果垃圾收集例程回收的內存分配量低于,則變量字面量和或數組元素的臨界值就會加倍。
基本類型和引用類型的值只挑本人重要的寫(有夾雜其他補充)
描述:基本類型值指的是簡單的數據段,而引用類型值指那些可能由多個值構成的對象。
動態的屬性
引用類型的值,我們可以為其添加屬性和方法,也可以改變和刪除其屬性和方法
var person = {}; person.name = "Nicholas"; alert(person.name); //"Nicholas"
不能給基本類型的值添加屬性,盡管這樣做不會導致任何錯誤
var name = "Nicholas"; name.age = 27; alert(name.age); //undefined
復制變量
變量是基本類型的值時,會在變量對象上創建一個新值,然后把該值復制
到為新變量分配的位置上
var num1 = 5; var num2 = num1; 此后,這兩個變量可以參與任 何操作而不會相互影響
變量是引用類型的值時,同樣也會將存儲在變量對象中的值復制一份放到為新變量分配的空間中。這個值的副本實際上是一個指針,而這個指針指向存儲在堆中的一個對象。
var obj1 = new Object(); var obj2 = obj1; obj1.name = "Nicholas"; alert(obj2.name); //"Nicholas"
傳遞參數
描述:所有函數的參數都是按值傳遞的。基本類型值復制,而引用類型值是按值。
基本類型值復制
function addTen(num) { num += 10; return num; } var count = 20; var result = addTen(count); alert(count); //20,沒有變化 alert(result); //30
引用類型值是按值
function setName(obj) { obj.name = "Nicholas"; } var person = {}; setName(person); alert(person.name); //"Nicholas" function setName(obj) { obj.name = "Nicholas"; obj = new Object(); obj.name = "Greg"; } var person = new Object(); setName(person); alert(person.name); //"Nicholas" 說明即使在函數內部修改了參數的值,但原始的引用仍然保持未變。實際上,當在函數內部重寫 obj 時,這 個變量引用的就是一個局部對象了。而這個局部對象會在函數執行完畢后立即被銷毀。執行環境及作用域
描述:定義了變量或函數有權訪問的其他數據,決定了它們各自的行為。每個執行環境都有一個與之關聯的變量對象(variable object),環境中定義的所有變量和函數都保存在這個對象中。
作用域鏈的用途,是保證對執行環境有權訪問的所有變量和函數的有序訪問。
延長作用域鏈
有些語句可以在作用域鏈的前端臨時增加一個變量對象,該變量對象會在代碼執行后被移除。在兩種情況下會發生這種現象。
try-catch 語句的 catch 塊; with 語句。 function buildUrl() { var qs = "?debug=true"; with(location){ var url = href + qs; } return url; } with 語句內部,則定義了一個名為 url 的變量,因而 url 就成了函數執行環境的一 部分,所以可以作為函數的值被返回。
沒有塊級作用域
一個 if 語句中定義了變量 color 但在 JavaScript 中, if 語句中的變量聲明會將變量添加到當前的執行環境(在這里是全局環境)中。(for 語句也一樣)
if (true) { var color = "blue"; } alert(color); //"blue"
聲明變量
使用 var 聲明的變量會自動被添加到最接近的環境中。
function add(num1, num2) { var sum = num1 + num2; return sum; } var result = add(10, 20); //30 alert
查詢標識符
當在某個環境中為了讀取或寫入而引用一個標識符時,必須通過搜索來確定該標識符實際代表什么。搜索過程從作用域鏈的前端開始,向上逐級查詢與給定名字匹配的標識符。如果在局部環境中找到了該標識符,搜索過程停止,變量就緒。如果在局部環境中沒有找到該變量名,則繼續沿作用域鏈向上搜索。搜索過程將一直追溯到全局環境的變量對象。如果在全局環境中也沒有找到這個標識符,則意味著該變量尚未聲明。
var color = "blue"; function getColor(){ return color; } alert(getColor()); //"blue"垃圾收集
描述:有自動垃圾收集機制,也就是說,執行環境會負責管理代碼執行過程中使用的內存。
標記清除
這是JavaScript最常見的垃圾回收方式,當變量進入執行環境的時候,比如函數中聲明一個變量,垃圾回收器將其標記為“進入環境”,當變量離開環境的時候(函數執行結束)將其標記為“離開環境”。 垃圾回收器會在運行的時候給存儲在內存中的所有變量加上標記,然后去掉環境中的變量以及被環境中變量所引用的變量(閉包),在這些完成之后仍存在標記的就是要刪除的變量了。
引用計數
在低版本IE中經常會出現內存泄露,很多時候就是因為其采用引用計數方式進行垃圾回收。引用計數的策略是跟蹤記錄每個值被使用的次數,當聲明了一個變量并將一個引用類型賦值給該變量的時候這個值的引用次數就加1,如果該變量的值變成了另外一個,則這個值得引用次數減1,當這個值的引用次數變為0的時 候,說明沒有變量在使用,這個值沒法被訪問了,因此可以將其占用的空間回收,這樣垃圾回收器會在運行的時候清理掉引用次數為0的值占用的空間。 在IE中雖然JavaScript對象通過標記清除的方式進行垃圾收,但BOM與DOM對象卻是通過引用計數回收垃圾的,也就是說只要涉及BOM及DOM就會出現循環引用問題。
性能問題
IE 的垃圾收集器是根據內存分配量運行的,具體一點說就是 256 個變量、4096 個對象(或數組)字面量和數組元素(slot)或者 64KB 的字符串。達到上述任何一個臨界值,垃圾收集器就會運行。這種實現方式的問題在于,如果一個腳本中包含那么多變量,那么該腳本很可能會在其生命周期中一直保有那么多的變量。而這樣一來,垃圾收集器就不得不頻繁地運行。結果,由此引發的嚴重性能問題促使 IE7 重寫了其垃圾收集程。隨著 IE7 的發布,其 JavaScript 引擎的垃圾收集例程改變了工作方式:觸發垃圾收集的變量分配、字面量和(或)數組元素的臨界值被調整為動態修正。IE7 中的各項臨界值在初始時與 IE6 相等。如果垃圾收集例程回收的內存分配量低于 15%,則變量、字面量和(或)數組元素的臨界值就會加倍。如果例程回收了 85%的內存分配量,則將各種臨界值重置回默認值。這一看似簡單的調整,極大地提升了 IE在運行包含大量 JavaScript 的頁面時的性能。
管理內存
確保占用最少的內存可以讓頁面獲得更好的性能。而優化內存占用的最佳方式,就是為執行中的代碼只保存必要的數據。一旦數據不再有用,最好通過將其值設置為 null 來釋放其引用——這個做法叫做解除引用(dereferencing)。
解除引用的真正作用是讓值脫離 執行環境,以便垃圾收集器下次運行時將其回收。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/89536.html
摘要:此時產生了閉包。導致,函數的活動對象沒有被銷毀。是不是跟你想的不一樣其實,這個例子重點就在函數上,這個函數的第一個參數接受一個函數作為回調函數,這個回調函數并不會立即執行,它會在當前代碼執行完,并在給定的時間后執行。 上一節說了執行上下文,這節咱們就乘勝追擊來搞搞閉包!頭疼的東西讓你不再頭疼! 一、函數也是引用類型的。 function f(){ console.log(not cha...
摘要:執行環境的類型有兩種全局全局執行環境局部函數執行環境每個環境都可以向上搜索作用域鏈,以查詢變量和函數名但任何環境都不能通過向下搜索作用域鏈而進入另一個執行環境。內部可通過作用域鏈訪問外部,外部不能訪問內部。 變量、作用域和內存問題 ECMAScript 數據類型 基本類型(5種): Undefined,Null,Boolean,Number,String typeof() 檢測...
摘要:閉包的注意事項通常,函數的作用域及其所有變量都會在函數執行結束后被銷毀。但是,在創建了一個閉包以后,這個函數的作用域就會一直保存到閉包不存在為止。最后通過釋放了和對閉包的引用。從而使用閉包模塊化代碼,減少全局變量的污染。 JavaScript 閉包 原文鏈接 什么是閉包(Closure) 簡單講,閉包就是指有權訪問另一個函數作用域中的變量的函數。 MDN 上面這么說:閉包是一種特殊的...
摘要:閉包的出現正好結合了全局變量和局部變量的優點。這就是閉包的一個使用場景保存現場。 前言 什么是閉包,其實閉包是可以重用一個對象,又保護對象不被篡改的一種機制。什么是重用一個對象又保護其不被篡改呢?請看下面的詳解。 作用域和作用域鏈 注意理解作用域和作用域鏈對理解閉包有非常大的幫助,所以我們先說一下作用域和作用域鏈 什么是作用域作用域表示的是一個變量的可用范圍、其實它是一個保存變量的對象...
摘要:如果在局部環境沒有找到該變量名,則繼續沿作用域鏈向上搜索。很明顯,訪問局部變量要比訪問全局變量更快,因為不用向上搜索作用域鏈。 按照ECMA-262定義,JavaScript的變量松散類型的本質,決定了: 它還只是在特定時間用于保存特定值的一個名字而已。 變量的值及其數據類型可以再腳本的生命周期內改變。 4.1 基本類型和引用類型的值 基本類型 簡單的數據段(Undefine...
閱讀 1847·2021-11-22 15:25
閱讀 3912·2021-11-17 09:33
閱讀 2507·2021-10-12 10:12
閱讀 1802·2021-10-09 09:44
閱讀 3235·2021-10-08 10:04
閱讀 1313·2021-09-29 09:35
閱讀 1947·2019-08-30 12:57
閱讀 1303·2019-08-29 16:22