變量
因爲JavaScript變量鬆散類型的本質,決定了它只是在特定時間用於保存特定值的一個名字而已。變量分爲基礎類型值和引用類型值;
基本類型值指的是簡單的數據段(Undefined、Null、Boolean、Number、String 和 symbol),而引用類型值指那些可能由多個值構成的對象。前端
引用類型的值是保存在內存中的對象。與其餘語言不一樣,JavaScript 不容許直接訪問內存中的位置, 也就是說不能直接操做對象的內存空間。在操做對象時,其實是在操做對象的引用而不是實際的對象。 爲此,引用類型的值是按引用訪問的
var obj1 = new Object();web
var obj2 = obj1; obj1.name = "Nicholas"; alert(obj2.name); //"Nicholas"
做用域鏈
1.執行環境
執行環境(execution context,爲簡單起見,有時也稱爲「環境」)定義了變量或函數有權訪問的其餘數據,決定了它們各自的行爲。
每一個函數都有本身的執行環境。當執行流進入一個函數時,函數的環境就會被推入一個環境棧中。 而在函數執行以後,棧將其環境彈出,把控制權返回給以前的執行環境。ECMAScript 程序中的執行流 正是由這個方便的機制控制着。
全局執行環境是最外層環境,web開發中一般認爲是window;某個執行環境中全部代碼執行完畢後,該環境將被銷燬,保存在其中的變量和函數也將同時被銷燬
2.當代碼在一個環境中執行時,會建立變量對象的一個做用域鏈(scope chain)。做用域鏈的用途,是保證對執行環境有權訪問的全部變量和函數的有序訪問。當前的執行環境就是做用域的最前端,標識符解析是沿着做用域鏈最前端向後回溯,直到找到標誌符
3.當某個函數被調用時,會建立一個執行環境(execution context)及相應的做用域鏈。 而後,使用 arguments 和其餘命名參數的值來初始化函數的活動對象(activation object)。
閉包
閉包是指有權訪問另外一個函數做用域中的變量的函數。建立閉包的常見方式,就是在一個函數內部建立另外一個函數。
不管何時在函數中訪問一個變量時,就會從做用域鏈中搜索具備相應名字的變量。通常來說, 當函數執行完畢後,局部活動對象就會被銷燬,內存中僅保存全局做用域(全局執行環境的變量對象)。 可是,閉包的狀況又有所不一樣。
外部函數執行結束後,執行環境就會在做用域鏈中銷燬,可是因爲閉包函數的局部做用域鏈仍在使用其活動對象,因此閉包函數被銷燬時外部活動環境才能被銷燬。
因爲閉包會攜帶包含它的函數的做用域,所以會比其餘函數佔用更多的內存。閉包
this
1.(默認綁定)普通函數調用;this指向windowapp
在嚴格模式下(strict mode),全局對象將沒法使用默認綁定,即執行會報undefined的錯誤函數
2.(隱式綁定)做爲對象方法調用;this指向調用對象this
3.做爲構造函數調用,this 指代實例對象spa
4.call() 和 apply()、bind()
主要是經過改變對象的prototype關聯對象。具體使用上,能夠經過這兩個方法call(…)或apply(…)來實現(大多數函數及本身建立的函數默認都提供這兩個方法)call與apply是一樣的做用,區別只是其餘參數的設置上,
apply:調用一個對象的一個方法,用另外一個對象替換當前對象。例如:B.apply(A, arguments);即A對象應用B對象的方法。prototype
call:調用一個對象的一個方法,用另外一個對象替換當前對象。例如:B.call(A, args1,args2);即A對象調用B對象的方法。code
bind:call和apply都是改變上下文中的this並當即執行這個函數,bind方法可讓對應的函數想何時調就何時調用,而且能夠將參數在執行的時候添加,這是它們的區別。
bind也能夠有多個參數,而且參數能夠執行的時候再次添加,可是要注意的是,參數是按照形參的順序進行的。對象