摘要:作用域鏈中的下一個(gè)變量對(duì)象來(lái)自包含外部環(huán)境,而再下一個(gè)變量對(duì)象則來(lái)自下一個(gè)包含環(huán)境。這樣,一直延續(xù)到全局執(zhí)行環(huán)境全局執(zhí)行環(huán)境的變量對(duì)象始終都是作用域鏈中的最后一個(gè)對(duì)象標(biāo)識(shí)符解析沿作用域鏈一級(jí)一級(jí)搜索標(biāo)識(shí)符。
一、寫(xiě)在前面
最近研究了創(chuàng)建Android虛擬機(jī)、vscode結(jié)合weex開(kāi)發(fā)Android APP、Vmware裝MAC虛擬機(jī)的事,看的內(nèi)容不夠多,接下來(lái)加油
二、變量、作用域和內(nèi)存問(wèn)題 2.1 基本類型、引用類型
變量類型:
基本類型: 簡(jiǎn)單數(shù)據(jù)段,按值訪問(wèn)的,可操作變量中的實(shí)際值
引用類型:對(duì)象,按引用訪問(wèn),操作對(duì)象的引用,能動(dòng)態(tài)添加屬性
變量復(fù)制:
基本類型:直接分配兩個(gè)內(nèi)存空間,互不影響
引用類型:復(fù)制了指針,指向堆中同一對(duì)象,相互影響
傳參(見(jiàn)示例):
基本類型傳值,互不影響
引用類型傳地址,相互影響
// 示例 function?setName(obj)?{ // 指向person,添加屬性name ????obj.name?=?"Nicholas"; ????// 指針指向新的內(nèi)存空間 ????obj?=?new?Object(); ????obj.name?=?"Greg"; // 函數(shù)執(zhí)行完畢后,局部對(duì)象立即銷毀 } var?person?=?new?Object(); setName(person); alert(person.name);????//"Nicholas"
檢測(cè)類型
typeOf特殊:null返回object
instanceof:引用類型檢測(cè),(某實(shí)例) instanceof (某類型)
2.2 執(zhí)行環(huán)境、作用域
執(zhí)行環(huán)境:定義變量或函數(shù)有權(quán)訪問(wèn)的其他數(shù)據(jù)范圍,決定行為。中有變量對(duì)象,保存環(huán)境中定義的所有變量和函數(shù),環(huán)境銷毀,變量、函數(shù)銷毀
全局執(zhí)行環(huán)境,web中為window對(duì)象
局部執(zhí)行環(huán)境,執(zhí)行流進(jìn)入函數(shù),函數(shù)環(huán)境被推入環(huán)境棧,執(zhí)行后,棧將其環(huán)境彈出,控制權(quán)返回之前的執(zhí)行環(huán)境
作用域鏈: 在環(huán)境中執(zhí)行代碼,會(huì)創(chuàng)建變量對(duì)象的作用域鏈,保證(有權(quán)訪問(wèn)當(dāng)前環(huán)境的)變量和對(duì)象有序訪問(wèn)
作用域鏈的前端,始終都是當(dāng)前執(zhí)行的代碼所在環(huán)境的變量對(duì)象。如果這個(gè)環(huán)境是函數(shù),則將其活動(dòng)對(duì)象(activation
object)作為變量對(duì)象。活動(dòng)對(duì)象在最開(kāi)始時(shí)只包含一個(gè)變量,即arguments對(duì)象(這個(gè)對(duì)象在全局環(huán)境中是不存在的)。作用域鏈中的下一個(gè)變量對(duì)象來(lái)自包含(外部)環(huán)境,而再下一個(gè)變量對(duì)象則來(lái)自下一個(gè)包含環(huán)境。這樣,一直延續(xù)到全局執(zhí)行環(huán)境;全局執(zhí)行環(huán)境的變量對(duì)象始終都是作用域鏈中的最后一個(gè)對(duì)象
標(biāo)識(shí)符解析:沿作用域鏈一級(jí)一級(jí)搜索標(biāo)識(shí)符。從作用域鏈前端開(kāi)始,逐級(jí)向后,直到找到標(biāo)識(shí)符為止
內(nèi)外關(guān)系:
內(nèi)部環(huán)境可以通過(guò)作用域鏈訪問(wèn)所有外部環(huán)境,外部環(huán)境不能訪問(wèn)內(nèi)部環(huán)境中的任何變量或函數(shù)
每個(gè)環(huán)境可以向上級(jí)搜素,但不能向下搜索進(jìn)入另一個(gè)執(zhí)行環(huán)境
2.3 延長(zhǎng)作用域鏈在作用域鏈前端加臨時(shí)變量對(duì)象,執(zhí)行后移除
try-catch中catch
with
function aaa( ) { var qs = "?id=12"; // 引用location,with內(nèi)部可用location的所有屬性和方法 with(location) { // href為locaiton.href var url = href + qs; } // 在aaa( )內(nèi)可拿到with( )內(nèi)定義的url return url; }
catch特殊情況:IE8以前catch的錯(cuò)誤對(duì)象會(huì)添加至執(zhí)行環(huán)境的變量對(duì)象,catch外也能訪問(wèn)(IE9修復(fù)了)
2.4 沒(méi)有塊級(jí)作用域{ } 封閉的代碼塊中定義的變量,執(zhí)行后沒(méi)有被銷毀,依舊存在于{ }外部執(zhí)行環(huán)境中
聲明變量
var:自動(dòng)添加到最接近的環(huán)境中。沒(méi)有var直接聲明,添加到全局環(huán)境中(嚴(yán)格模式下導(dǎo)致錯(cuò)誤,不推薦)
查詢標(biāo)識(shí)符
從作用域鏈前端開(kāi)始,向上逐級(jí)查詢,直至匹配為止(先自身再向上)
訪問(wèn)局部變量比訪問(wèn)全局變量更快
2.5 垃圾收集執(zhí)行環(huán)境管理著代碼執(zhí)行過(guò)程中使用的內(nèi)存
自動(dòng)垃圾收集機(jī)制:實(shí)現(xiàn)所需內(nèi)存分配、無(wú)用內(nèi)存回收,自動(dòng)管理。固定時(shí)間間隔,周期性檢索不再繼續(xù)使用的變量,打標(biāo)記,釋放其占用的內(nèi)存
回收策略
標(biāo)記清除(主流)
變量進(jìn)入環(huán)境、離開(kāi)環(huán)境,標(biāo)記不同
標(biāo)記方式:翻轉(zhuǎn)某位,或以環(huán)境列表、離開(kāi)環(huán)境列表區(qū)分,或其他
運(yùn)行機(jī)制:內(nèi)存中全部變量加標(biāo)記,再去掉環(huán)境中的、被環(huán)境中引用的變量的標(biāo)記,剩下還有標(biāo)記的,準(zhǔn)備刪除,垃圾收集器清除內(nèi)存,銷毀值,回收空間
引用計(jì)數(shù)(不常見(jiàn))
跟蹤每個(gè)值被引用的次數(shù)
計(jì)數(shù)規(guī)則:引用類型的值賦給一個(gè)變量,引用次數(shù)加一;已經(jīng)引用的變量不再引用它,引用次數(shù)減一
運(yùn)行機(jī)制:垃圾收集器運(yùn)行,釋放引用次數(shù)為0的值所占的內(nèi)存。
特殊情況:
循環(huán)引用(例:兩對(duì)象間相互引用,則引用次數(shù)永不為0,無(wú)法銷毀)
IE9之前,BOM、DOM對(duì)象以COM(使用引用計(jì)數(shù)策略)形式實(shí)現(xiàn),循環(huán)引用后刪除DOM,對(duì)應(yīng)值也不會(huì)回收(通過(guò)賦值null,手動(dòng)斷開(kāi)循環(huán)引用解決)。IE9后,BOM、DOM轉(zhuǎn)為真正的js對(duì)象,避免了該問(wèn)題
性能問(wèn)題
IE7之前:內(nèi)存分配量達(dá)到任一臨界值(256變量、4096對(duì)象數(shù)組、64K字符串)則回收,缺點(diǎn):如一直在臨界值之上,則一直回收
IE7修正:臨界值動(dòng)態(tài)修正,初始與之前相等,回收的分配量低于15%,臨界值加倍,回收的內(nèi)存分配量85%,臨界值恢復(fù)初始
手動(dòng)觸發(fā)方式(不推薦):
// 手動(dòng)觸發(fā)方式 // IE window.CollectGarbage(); // Opear7~ window.opera.collect();
管理內(nèi)存
內(nèi)存分配:給web瀏覽器的少于給桌面應(yīng)用的,防止系統(tǒng)崩潰
優(yōu)化內(nèi)存占用:只保存必要數(shù)據(jù),不用的置null(解除引用,給全局中的用,局部的會(huì)自動(dòng)銷毀),等待下一次垃圾回收
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/104964.html
摘要:具體說(shuō)就是執(zhí)行流進(jìn)入下列任何一個(gè)語(yǔ)句時(shí),作用域鏈就會(huì)得到加長(zhǎng)語(yǔ)句的塊。如果局部環(huán)境中存在著同名的標(biāo)識(shí)符,就不會(huì)使用位于父環(huán)境中的標(biāo)識(shí)符訪問(wèn)局部變量要比訪問(wèn)全局變量更快,因?yàn)椴挥孟蛏纤阉髯饔糜蜴湣? 基本類型和引用類型的值 ECMAscript變量包含 基本類型值和引用類型值 基本類型值值的是基本數(shù)據(jù)類型:Undefined, Null, Boolean, Number, String ...
摘要:局部變量只在函數(shù)執(zhí)行過(guò)程中存在。此時(shí),局部變量就沒(méi)有存在的必要了,因此可以釋放他們所占的內(nèi)存以供他們使用。引用計(jì)數(shù)的含義是跟蹤記錄每個(gè)值被引用的次數(shù)。這一做法適合于大多數(shù)全局變量和局部變量的屬性。 基本類型和引用類型的值 ECMAScript變量可能包含兩種不同數(shù)據(jù)類型的值:基本類型值和引用類型值?;绢愋椭抵傅氖呛?jiǎn)單的數(shù)據(jù)段,而引用類型的值指那些可能有多個(gè)值構(gòu)成的對(duì)象。 動(dòng)態(tài)的屬性 ...
摘要:因此,所有在方法中定義的變量都是放在棧內(nèi)存中的當(dāng)我們?cè)诔绦蛑袆?chuàng)建一個(gè)對(duì)象時(shí),這個(gè)對(duì)象將被保存到運(yùn)行時(shí)數(shù)據(jù)區(qū)中,以便反復(fù)利用因?yàn)閷?duì)象的創(chuàng)建成本通常較大,這個(gè)運(yùn)行時(shí)數(shù)據(jù)區(qū)就是堆內(nèi)存。 上一篇:《javascript高級(jí)程序設(shè)計(jì)》筆記:繼承近幾篇博客都會(huì)圍繞著圖中的知識(shí)點(diǎn)展開(kāi) showImg(https://segmentfault.com/img/bVY0C4?w=1330&h=618);...
摘要:閉包是怎么通過(guò)作用域鏈霸占更多內(nèi)存的本文是作者學(xué)習(xí)高級(jí)程序設(shè)計(jì)第一小節(jié)的一點(diǎn)個(gè)人理解,詳細(xì)教程請(qǐng)參考原教材。函數(shù)執(zhí)行過(guò)程創(chuàng)建了一個(gè)函數(shù)的活動(dòng)對(duì)象,作用域鏈的最前端指向這個(gè)對(duì)象。函數(shù)執(zhí)行完畢返回值后執(zhí)行環(huán)境作用域鏈和活動(dòng)對(duì)象一并銷毀。 JavaScript 閉包是怎么通過(guò)作用域鏈霸占更多內(nèi)存的? 本文是作者學(xué)習(xí)《JavaScript 高級(jí)程序設(shè)計(jì)》7.2第一小節(jié)的一點(diǎn)個(gè)人理解,詳細(xì)教程請(qǐng)...
摘要:定義函數(shù)表達(dá)式的方式有兩種函數(shù)聲明。不過(guò),這并不是匿名函數(shù)唯一的用途。可以使用命名函數(shù)表達(dá)式來(lái)達(dá)成相同的結(jié)果閉包匿名函數(shù)和閉包是兩個(gè)概念,容易混淆。匿名函數(shù)的執(zhí)行環(huán)境具有全局性,因此其對(duì)象通常指向通過(guò)改變函數(shù)的執(zhí)行環(huán)境的情況除外。 定義函數(shù)表達(dá)式的方式有兩種: 函數(shù)聲明。它的重要特征就是 函數(shù)聲明提升(function declaration hoisting) 即在執(zhí)行代碼之前會(huì)...
閱讀 3325·2021-11-12 10:36
閱讀 2483·2021-11-02 14:43
閱讀 2156·2019-08-30 14:23
閱讀 3470·2019-08-30 13:08
閱讀 928·2019-08-28 18:09
閱讀 3141·2019-08-26 12:22
閱讀 3154·2019-08-23 18:24
閱讀 2024·2019-08-23 18:17