摘要:變量作用域和內(nèi)存問題基本類型和引用類型的值基本類型就是簡單的數(shù)據(jù)段種值類型,而引用類型就是對象操控對象的引用。但是不但能訪問自己的變量,也能訪問和全局作用域下的變量。延長作用域鏈相當于創(chuàng)造了一個新的變量對象在當前作用域的上方。
變量作用域和內(nèi)存問題 1.基本類型和引用類型的值
基本類型就是簡單的數(shù)據(jù)段(5種值類型),而引用類型就是對象(操控對象的引用)。1.1復制變量值
引用類型實際上在復制的時候,傳遞的是函數(shù)的指針,復制完成后,實際兩個變量引用的都是同一個堆內(nèi)存中的對象,改變這個對象,兩個變量的值也會同步改變。
1.2傳遞參數(shù)函數(shù)的參數(shù)都是按值傳遞的。其實我認為這種說法多少還是有些抽象??偨Y(jié)起來不如這樣說。當傳遞給函數(shù)的變量是值類型時,那么傳遞給函數(shù)的這個原始變量的值不會隨函數(shù)內(nèi)部的影響而改變。當傳遞給函數(shù)的變量是引用類型(object)時,那么傳遞給函數(shù)的這個原始變量的引用不會隨函數(shù)內(nèi)部的影響而改變。其實這里不是太容易理解,比如舉個例子來說明
var obj = { name: "andy" } function ChangeObj(val) { val.age = "25" val = { name:"zakas", age:40 } return val; } ChangeObj(obj); // {name:"zakas",age:40} console.log(obj) // {name:"andy",age:25}
上面這個例子中,函數(shù)中val的內(nèi)存地址變了(引用變了),如果函數(shù)是按引用傳遞的話,那么val的引用就是obj的引用,val的應用變了,obj的引用也會跟隨變化,所以obj的結(jié)果也應該是{name:"zakas",age:40}。而按值傳遞的話,obj賦值給val它的引用,但是他倆的引用是不關(guān)聯(lián)在一起的,val引用的改變并不會影響obj的引用地址。
函數(shù)的形參就是函數(shù)作用域中的局部變量。當函數(shù)運行完是會被銷毀的。
1.3檢測類型instanceof 可以進行引用類型的更明確的檢測。所以值類型在instanceof總?cè)莊alse,值類型也沒必要用其方法進行檢測。instanceof只能區(qū)分Array Object 和 RegExp
2.執(zhí)行環(huán)境每個執(zhí)行環(huán)境都有一個變量對象,變量對象的概念很重要。它是作用域中所有定義的變量的一個大的集合;每個執(zhí)行環(huán)境都有一個變量對象,存儲著我們定義的所有變量,但是這個變量對象我們訪問不到,但解析器處理數(shù)據(jù)時會在后臺使用它。
function A() { var tempA; function B() { var tempB; function C() { var tempC } } }
B()的作用域鏈中包含3個對象,一個是自己的變量對象,還有A的變量對象和全局變量對象。A()中的作用域鏈包含2個對象,一個A()自己的變量對象,還有就是全局變量對象。因此A訪問不了B的變量,只能訪問自己的和全局的變量。但是B不但能訪問自己的變量,也能訪問A和全局作用域下的變量。
2.1延長作用域鏈with
With相當于創(chuàng)造了一個新的變量對象在當前作用域的上方。例如:
var obj = { name:"andy", sex:"man", hobby:"game" } function fn() { with(obj) { fnName = name; fnSex = sex; fnHobby = hobby; } console.log(fnName,fnSex,fnHobby) // andy,man,game } fn()
With方法會造成性能的嚴重損失,所以一般不建議用
2.2無塊級作用域必須要知道這個概念,作用和區(qū)別,最老生常談的一個問題:
for(var i =0 ; i < 10 ; i++ ) { setTimeout(function(){ console.log(i); },0) }
在理解這個問題的前提下,首先要知道定時器是異步的,即使是0,也要先放到緩存區(qū)中,當其他程序自上而下執(zhí)行完畢之后再去調(diào)用。所以在其他程序自上而下執(zhí)行完畢之后,由于沒有塊級作用域,i是全局的,已經(jīng)變成10了,所以輸出10個10。如果把i改為存在塊級作用域的let,那么問題就迎刃而解了。
for(let i =0 ; i < 10 ; i++ ) { setTimeout(function(){ console.log(i); },0) }2.3垃圾收集
JavaScript具有自動垃圾收集機制
使用值的過程中,其實是相當于對變量分配的內(nèi)存進行寫入和讀取的操作。JavaScript在創(chuàng)建變量的過程會分配內(nèi)存,當變量不用時會自動釋放掉,這個過程叫做垃圾回收機制,但是這個自動是混亂的根源,很多開發(fā)者因此覺得不用太關(guān)心內(nèi)存問題,這是錯誤的。
原理:垃圾處理器會在默認情況下周期的進行檢測,找出那些不用的變量,然后釋放其內(nèi)存。
回收策略:在局部環(huán)境中,函數(shù)調(diào)用完之后,垃圾收集器會跟蹤哪個變量有用,哪個變量沒有用,對于沒用的變量,打上標記,以備回收其內(nèi)存,但是標記的方法通常有另兩個策略:
標記清除:從2012年起,所有瀏覽器全部使用標記清除的方法進行垃圾回收,并且所有對js垃圾回收的改進也是基于標記清除的方法進行算法優(yōu)化。
引用計數(shù):這個由于存在嚴重的循環(huán)引用問題,所以現(xiàn)在已經(jīng)基本不用了。
因此,當寫的程序占用較少的內(nèi)存是高性能頁面的一個很重要的點。所以當我們寫程序時候,一旦數(shù)據(jù)不用了,最好設置成null來解除引用
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/96546.html
摘要:執(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() 檢測...
摘要:使用聲明的變量會動被添加到最近的環(huán)境中查詢標識符,現(xiàn)在作用域鏈的最前端開始搜索,逐步向上級查詢,直到找到匹配的標識符,在變量查詢中,訪問局部變量要比全局變量更快,因為不需要向上搜索作用域。 基本類型和引用類型的值 基本類型值指的是簡單的數(shù)據(jù)段;引用類型值指那些可能由多個值構(gòu)成的對象。不能給基本類型添加屬性,可以給引用類型值動態(tài)的添加屬性。 基本類型按值訪問,存放在棧內(nèi)存中。引用類型按引...
摘要:在操作對象時,實際上是在操作對象的引用而不是實際的對象。為此,引用類型的值是按引用訪問的。標記清除是目前主流的垃圾收集算法,這種算法的思想是給當前不使用的值加上標記,然后再回收其內(nèi)存 1.在操作對象時,實際上是在操作對象的引用而不是實際的對象。為此,引用類型的值是按引用訪問的。 2.當從一個變量向另一個變量復制引用類型的值時,兩個變量實際上將引用同一個對象,因此,改變其中一個變量,就會...
摘要:不允許直接訪問內(nèi)存中的位置,也就是說不能直接操作對象的內(nèi)存空間。在操作對象時,實際上是在操作對象的引用而不是實際的對象。解除引用的真正作用是讓值脫離執(zhí)行環(huán)境,以便垃圾收集器下次運行時將其回收 1 基本類型和引用類型的值 基本數(shù)據(jù)類型是按值訪問的,因為可以操作保存在變量中的實際的值 基本類型值在內(nèi)存中占據(jù)固定大小的空間,因此被保存在棧內(nèi)存中 引用類型的值是保存在內(nèi)存中的對象。JavaSc...
摘要:全局變量是最外圍的一個執(zhí)行環(huán)境,代碼在環(huán)境中執(zhí)行,會創(chuàng)建一個作用域鏈,用途是保證對執(zhí)行環(huán)境有權(quán)訪問所有變量和函數(shù)的有序訪問。作用域鏈中最后一個對象始終是全局執(zhí)行環(huán)境。內(nèi)部環(huán)境可以通過作用域鏈訪問所有的外部環(huán)境,外部則不能訪問內(nèi)部。 1、基本類型和引用類型的值 * 基本類型 : 指的是簡單的數(shù)據(jù)段,五種基本類型是按值訪問的,可以直接操作保存在變量中實際的值。 * 引用類型 : 指那些可能...
閱讀 2217·2021-11-15 11:36
閱讀 1383·2021-10-14 09:42
閱讀 4206·2021-09-30 09:52
閱讀 1711·2021-09-24 10:24
閱讀 963·2021-09-02 09:56
閱讀 2685·2019-08-30 13:11
閱讀 3060·2019-08-30 13:06
閱讀 943·2019-08-30 12:56