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