摘要:不是引用類(lèi)型,無(wú)法輸出簡(jiǎn)而言之,堆內(nèi)存存放引用值,棧內(nèi)存存放固定類(lèi)型值。變量的查詢?cè)谧兞康牟樵冎?,訪問(wèn)局部變量要比全局變量來(lái)得快,因此不需要向上搜索作用域鏈。
贊助我以寫(xiě)出更好的文章,give me a cup of coffee?
2017最新最全前端面試題
基本類(lèi)型值有:undefined,NUll,Boolean,Number和String,這些類(lèi)型分別在內(nèi)存中占有固定的大小空間,他們的值保存在??臻g,我們通過(guò)按值來(lái)訪問(wèn)的。
(1)值類(lèi)型:數(shù)值、布爾值、null、undefined。 (2)引用類(lèi)型:對(duì)象、數(shù)組、函數(shù)。
如果賦值的是引用類(lèi)型的值,則必須在堆內(nèi)存中為這個(gè)值分配空間。由于這種值的大小不固定(對(duì)象有很多屬性和方法),因此不能把他們保存到棧內(nèi)存中。但內(nèi)存地址大小是固定的,因此可以將內(nèi)存地址保存在棧內(nèi)存中。
簡(jiǎn)而言之,堆內(nèi)存存放引用值,棧內(nèi)存存放固定類(lèi)型值?!耙谩笔且粋€(gè)指向?qū)ο髮?shí)際位置的指針。
在這里需注意的是,引用指向的是具體的對(duì)象,而不是另一個(gè)引用。
這里的對(duì)象可以是字符串對(duì)象,數(shù)字對(duì)象,數(shù)組對(duì)象等
復(fù)制變量值再看下面這個(gè)例子:
由以上可以得出:在變量復(fù)制方面,基本類(lèi)型和引用類(lèi)型也有所不同,基本類(lèi)型復(fù)制的是值本身,而引用類(lèi)型復(fù)制的是地址。
傳遞參數(shù)ECMAScript中,所有函數(shù)的參數(shù)都是按值傳遞的,
js沒(méi)有按引用傳遞的,如果存在引用傳遞的話,那么函數(shù)內(nèi)的變量將是全局變量,在外部也可以訪問(wèn)。但這明顯是不可能的。
執(zhí)行環(huán)境及作用域執(zhí)行環(huán)境是javascript中最為重要的概念之一,執(zhí)行環(huán)境定義了變量或函數(shù)有權(quán)訪問(wèn)其他數(shù)據(jù)。
全局執(zhí)行環(huán)境是最外圍的執(zhí)行環(huán)境,在web瀏覽器中,全局執(zhí)行環(huán)境是window對(duì)象,因此,所有的全局變量的函數(shù)都是作為window的屬性和方法創(chuàng)建的。
當(dāng)執(zhí)行環(huán)境內(nèi)的代碼執(zhí)行完畢后,該環(huán)境被銷(xiāo)毀,保存其中的變量和函數(shù)也隨之銷(xiāo)毀,如果是全局環(huán)境,需所有程序執(zhí)行完畢或網(wǎng)頁(yè)完畢后才會(huì)銷(xiāo)毀。
去掉var的局部變量 通過(guò)傳參,也是局部變量函數(shù)體內(nèi)還包含函數(shù),只有這個(gè)函數(shù)才可以訪問(wèn)內(nèi)一層的函數(shù)
可以通過(guò)如下方法進(jìn)行訪問(wèn):
再一個(gè)作用域例子:
當(dāng)代碼在一個(gè)環(huán)境中執(zhí)行的時(shí)候,就會(huì)形成一種叫做作用域鏈的東西,它的用途是保證對(duì)執(zhí)行環(huán)境中有訪問(wèn)權(quán)限的變量和函數(shù)進(jìn)行有序訪問(wèn)(指按照規(guī)則層次來(lái)訪問(wèn)),作用域鏈的前端,就是執(zhí)行環(huán)境的變量對(duì)象。
作用域變量沒(méi)有在函數(shù)內(nèi)聲明或者聲明的時(shí)候沒(méi)有帶var就是全局變量,擁有全局作用域,window對(duì)象的所有屬性擁有全局作用域;在代碼任何地方都可以訪問(wèn),函數(shù)內(nèi)部聲明并且以var修飾的變量就是局部變量,只能在函數(shù)體內(nèi)使用,函數(shù)的參數(shù)雖然沒(méi)有使用var但仍然是局部變量。
沒(méi)有塊級(jí)作用域// if語(yǔ)句:
for循環(huán)語(yǔ)句也是如此。
變量的查詢在變量的查詢中,訪問(wèn)局部變量要比全局變量來(lái)得快,因此不需要向上搜索作用域鏈。
如下例子:
每個(gè)環(huán)境都可以向上搜索作用域鏈,以查詢變量和函數(shù)名;但任何環(huán)境都不能通過(guò)向下搜索作用域鏈而進(jìn)入另一個(gè)執(zhí)行環(huán)境。在這里,如果去掉var name = "trigkit4",那么將彈出“Jack”
內(nèi)存問(wèn)題javascript具有自動(dòng)垃圾回收機(jī)制,一旦數(shù)據(jù)不再使用,可以將其設(shè)為"null"來(lái)釋放引用
循環(huán)引用一個(gè)很簡(jiǎn)單的例子:一個(gè)DOM對(duì)象被一個(gè)Javascript對(duì)象引用,與此同時(shí)又引用同一個(gè)或其它的Javascript對(duì)象,這個(gè)DOM對(duì)象可能會(huì)引發(fā)內(nèi)存泄露。這個(gè)DOM對(duì)象的引用將不會(huì)在腳本停止的時(shí)候被垃圾回收器回收。要想破壞循環(huán)引用,引用DOM元素的對(duì)象或DOM對(duì)象的引用需要被賦值為null。
閉包在閉包中引入閉包外部的變量時(shí),當(dāng)閉包結(jié)束時(shí)此對(duì)象無(wú)法被垃圾回收(GC)。
var a = function() { var largeStr = new Array(1000000).join("x"); return function() { return largeStr; } }();DOM泄露
當(dāng)原有的COM被移除時(shí),子結(jié)點(diǎn)引用沒(méi)有被移除則無(wú)法回收。
var select = document.querySelector; var treeRef = select("#tree"); //在COM樹(shù)中l(wèi)eafRef是treeFre的一個(gè)子結(jié)點(diǎn) var leafRef = select("#leaf"); var body = select("body"); body.removeChild(treeRef); //#tree不能被回收入,因?yàn)閠reeRef還在 //解決方法: treeRef = null; //tree還不能被回收,因?yàn)槿~子結(jié)果leafRef還在 leafRef = null; //現(xiàn)在#tree可以被釋放了。Timers計(jì)(定)時(shí)器泄露
定時(shí)器也是常見(jiàn)產(chǎn)生內(nèi)存泄露的地方:
for (var i = 0; i < 90000; i++) { var buggyObject = { callAgain: function() { var ref = this; var val = setTimeout(function() { ref.callAgain(); }, 90000); } } buggyObject.callAgain(); //雖然你想回收但是timer還在 buggyObject = null; }調(diào)試內(nèi)存
Chrome自帶的內(nèi)存調(diào)試工具可以很方便地查看內(nèi)存使用情況和內(nèi)存泄露:
在 Timeline -> Memory 點(diǎn)擊record即可:
相關(guān)文章:
詳解js閉包我們可以利用閉包來(lái)突破作用域鏈,詳解js閉包
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/85307.html
摘要:注此讀書(shū)筆記只記錄本人原先不太理解的內(nèi)容經(jīng)過(guò)閱讀你不知道的后的理解。作用域及閉包基礎(chǔ),代碼運(yùn)行的幕后工作者引擎及編譯器。 注:此讀書(shū)筆記只記錄本人原先不太理解的內(nèi)容經(jīng)過(guò)閱讀《你不知道的JS》后的理解。 作用域及閉包基礎(chǔ),JS代碼運(yùn)行的幕后工作者:引擎及編譯器。引擎負(fù)責(zé)JS程序的編譯及執(zhí)行,編譯器負(fù)責(zé)詞法分析和代碼生成。那么作用域就像一個(gè)容器,引擎及編譯器都從這里提取東西。 ...
摘要:那其實(shí)閉包的原因就是外層函數(shù)的作用域?qū)ο鬅o(wú)法釋放其實(shí)就是一個(gè)函數(shù)調(diào)用會(huì)生成的臨時(shí)作用域圖中可看出其實(shí)就是在中的匿名函數(shù),所以他的就指向留下的作用域。 引言 網(wǎng)絡(luò)上關(guān)于作用域及閉包的文章很多,自己對(duì)于純理論知識(shí)并不能很快的理解,但自己對(duì)于圖畫(huà)有很強(qiáng)的記憶和理解能力,因此決定將此知識(shí)點(diǎn)以圖畫(huà)的知識(shí)表現(xiàn)出來(lái),加深自身理解的同時(shí)如果能幫到正在學(xué)習(xí)的童鞋就再好不過(guò)了 下面我以函數(shù)的整個(gè)生命周期來(lái)...
摘要:將作用域賦值給變量這里的作用域是,而不是將作用域賦值給一個(gè)變量閉包返回瀏覽器中內(nèi)存泄漏問(wèn)題大家都知道,閉包會(huì)使變量駐留在內(nèi)存中,這也就導(dǎo)致了內(nèi)存泄漏。 上一章我們講了匿名函數(shù)和閉包,這次我們來(lái)談?wù)勯]包中作用域this的問(wèn)題。 大家都知道,this對(duì)象是在運(yùn)行時(shí)基于函數(shù)的執(zhí)行環(huán)境綁定的,如果this在全局就是[object window],如果在對(duì)象內(nèi)部就是指向這個(gè)對(duì)象,而閉包卻是在運(yùn)行...
摘要:模仿塊級(jí)作用域在塊級(jí)語(yǔ)句中定義的變量,實(shí)際上是包含函數(shù)中而非語(yǔ)句中創(chuàng)建的。避免對(duì)全局作用域產(chǎn)生不良影響這種方式可以通過(guò)創(chuàng)建私有作用域,避免對(duì)全局作用域產(chǎn)生不良影響。一般包括函數(shù)的參數(shù)局部變量和內(nèi)部定義的其他函數(shù)。 模仿塊級(jí)作用域 在塊級(jí)語(yǔ)句中定義的變量,實(shí)際上是包含函數(shù)中而非語(yǔ)句中創(chuàng)建的。如: function outputNumbers(x){ for (var i = 0;...
摘要:什么是閉包給出的官方回答是閉包是由函數(shù)以及創(chuàng)建該函數(shù)的詞法環(huán)境組合而成。這就是閉包的核心。當(dāng)函數(shù)執(zhí)行完后,被作為返回值函數(shù)保留在了作用域中。閉包還有一個(gè)作用是模擬私有方法和變量。閉包的缺點(diǎn)由上文可知閉包的作用可以使數(shù)據(jù)保存在內(nèi)存中。 什么是閉包?MDN給出的官方回答是閉包是由函數(shù)以及創(chuàng)建該函數(shù)的詞法環(huán)境組合而成。這個(gè)環(huán)境包含了這個(gè)閉包創(chuàng)建時(shí)所能訪問(wèn)的所有局部變量 看代碼 //一個(gè)函數(shù)里...
閱讀 1745·2021-11-22 15:33
閱讀 2135·2021-10-08 10:04
閱讀 3575·2021-08-27 13:12
閱讀 3448·2019-08-30 13:06
閱讀 1492·2019-08-29 16:43
閱讀 1418·2019-08-29 16:40
閱讀 814·2019-08-29 16:15
閱讀 2774·2019-08-29 14:13