javascript 變數、範圍和記憶體問題

來源:互聯網
上載者:User

標籤:type   自己的   改變   for   isarray   好用   代碼   錯誤   參考型別   

一、基本類型和參考型別的值  

1.基本類型和參考型別的值 

基本類型值:指那些儲存在棧記憶體中的簡單資料,即這種值完全儲存在記憶體中的一個位置,他們所佔據的空間大小是固定的。

參考型別值:指那些儲存在堆記憶體中的對象,這些類型的真正資料是儲存在堆記憶體中的,而同時在棧記憶體中儲存的只是一個指標這個指標指向的是這個對象在堆記憶體中的一塊地址

基本類型的複製:基本類型在記憶體中佔有的空間大小是固定的,複製的時候會重新在棧記憶體中開闢一塊空間,是按值來訪問的。 

參考型別的複製:由於這種對象所佔的大小是不固定的,是放在堆記憶體中的,但是記憶體的地址大小是固定的,故棧中存放的是對象在堆記憶體的地址。這樣當尋找引用的時候,是先從棧記憶體中取出地址,然後再到堆記憶體中找到對應的值,這就是引用訪問。複製的時候是複製的棧記憶體的值,也就是拷貝的一個引用而已,兩個變數指向的堆記憶體中對象還是同一個對象。

 

2.複製變數的值    

基本類型:複製的是變數本身的值,複製後是在棧空間重新開闢一塊空間,複製完成後兩個變數是相互獨立的,各不相干,故一個變數的值改變後不會影響另外一個變數的值。  

參考型別:複製的時候只是複製的棧空間的地址而堆記憶體中還是同一個對象,也就是複製的引用,結果是兩個變數指向的是同一個記憶體塊,所以,複製後兩個變數中某一個改變了對象的值那麼另外一個變數輸出的結果也會改變,因為他們是指向的記憶體中同一個對象。

 

3.傳遞參數

在js中參數傳遞都是值傳遞,不存在引用傳遞。 

實值型別:傳遞的是變數本身的值,和複製是一樣的,函數中改變了變數的值,不會影響源變數值    

參考型別:同樣是值傳遞,傳遞的是變數再棧記憶體空間中的地址值,如果在函數中改變了對象某一個屬性的值,源變數中的值也會改變,因為在堆記憶體中它們是指向的同一個對象。

function func(num){    num.name=123;}var box={};box.name=‘abcd‘;alert(box.name);    //abcdfunc(box);alert(box.name);    //123   值在函數func中被改變了

 

4.檢測類型

 檢測變數的類型的時可以用 typeof 來實現,但是這個只是返回的幾大基本的資料類型,在檢測Object類型的時候則不是那麼好用,因為Null,Object,Array,RegExp 等都會返回object,那樣就不知道變數到底是什麼類型。    

可以 用instanceof 來確定變數是某種具體的參考型別。

var box = [1,2,3]

alert(box instanceof Object);  //truealert(box instanceof Array);  console.log(Array.isArray(box))  //true  //準確檢測類型是否是數組 如果是這種類型就返回true,否則就返回false

 

二、執行環境及範圍

 

執行環境也就是範圍在很多的程式設計語言中都是一個很重要的概念,規定了變數或者函數有權訪問其他資料的許可權,規定了各自的行為。    

全域執行環境是最外圍的執行環境,在web瀏覽器中,全域執行環境被認為是window對象,故所有的全域變數和函數都是以window對象的屬性和方法建立的。

每個函數都有自己的執行環境當執行環境中代碼執行完成後,就會銷毀該執行環境,也會銷毀裡面的變數和函數等。(全域執行環境是需要在網頁關閉或者應用程式退出後才會被銷毀。)   

 

當代碼在一個環境中執行時,會建立變數對象的一個範圍鏈,範圍鏈的用途是保證執行環境有權訪問的所有變數和函數的有序訪問。

函數體內還包含著函數,只有這個函數才可以訪問內一層的函數。而內建函式的變數可以通過範圍鏈訪問外部函數的變數,可以向上搜尋範圍鏈,以查詢變數。但是不能反過來。

 

沒有塊級範圍

  塊級範圍表示諸如if等有花括弧封閉的程式碼片段塊,所以支援條件判斷來定義變數。 像 if,for 等代碼塊中定義的變數在花括弧外面是可以訪問的,這和其他語言中有很大的差別。

if(true){    var color = ‘red‘;}console.log(color);     //red

 

var關鍵字在函數中的區別

在函數中聲明變數的時候,如果不加上關鍵字 var 那變數會被認為是全域的,函數外面也可以訪問它,當然在訪問之前要先執行一次函數,加了則是局部的

最好不要不用var關鍵字就初始設定變數,因為這種情況下可能會導致各種錯誤,所有初始設定變數的時候一定要加上關鍵字 var。

一般確定某一個變數的時候是通過搜尋來確定的,現在本級範圍上找,如果沒有,在向上級範圍找,依次類推,故訪問局部變數要比訪問全域變數的效率更高。因為不需要向上收索範圍鏈

 

3、記憶體相關 

  js中也存在記憶體回收機制,我們不需要擔心記憶體的泄露問題,記憶體回收機制會自動的管理記憶體的分配和無用記憶體的回收。  

  JS中最常用的記憶體回收的方式是標記清除,就是在啟動並執行時候會給記憶體中的所有變數加上一個標記,然後去掉環境中正在使用的變數的標記,而沒有被去掉標記的變數將被視為準備刪除的變數。最後垃圾清除程式完成記憶體清理的工作,銷毀那些帶有標記的變數,並且回收他們所佔用的記憶體空間 。   

  垃圾收集器是周期性的運行,不是隨時運行,這樣可能會遇到一些效能問題,但是一般情況下不需要擔心這個問題。

  一般來說,確保頁面佔用的記憶體更少可以讓頁面獲得更好的效能,最好的減少記憶體佔用量的方式就是,一旦變數或者對象不再使用的時候,將其賦值為空白,即:box=null; 來釋放引用,這種方式叫做刪除引用,這種方式使用大多數的全域變數和全域對象。

 

javascript 變數、範圍和記憶體問題

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.