JavaScript中作用,作用域鏈和閉包詳解
一、作用域
在js中有全局變量和局部變量之分:
比如
var a = 1;
function sum(){
var b=1
console.log(b) //1
console.log(a) //2
}
sum()
console.log(a) //3
console.log(b) //4
例子中 a 是全局變量,b是局部變量(定義在函數內部,只能在函數內部訪問)所以第1行正確
函數內部也能訪問全局變量 a所以第2行也能正確 第三行也正確。第4行有外部不能訪問
內部變量。變量聲明的時候初始化,局部變量在函數調用完時候銷毀,全局變量在頁面關閉時候銷毀
(注意如何b沒有用var修飾,就默認是全局變量)
二、js函數
1、function 函數名(){
}
2、匿名函數 function(){}
3、立即執行函數又名表達式函數
(function(i){
//dosometing
})(i)
4、私有函數
function a(){
function b(){ ====私有函數
}}
5、var 發=new Function(//dosomething)
6、變量的提升 函數提升
函數的生命周期
1、在函數創建階段,JS解析引擎進行預解析,會將函數聲明提前,同時將該函數放到全局作用域中(js中函數是一等公民優先考慮)或當前函數的上一級函數的局部作用域中。
在函數
執行階段,會創建該函數的執行上下文并且JS引擎會將當前函數的局部變量和內部函數進行聲明提前,然后再執行業務代碼,當函數執行完退出時,釋放該函數的執行上下文,并注銷該函數
的局部變量。
2、函數聲明大于變量聲明()
三、作用域鏈
1、在JS中運行中 當某個函數第一次被調用時 ,就會創建一個執行環境(execution context)以及相應的作用域鏈在js中將聲明的變量、參數、私有函數封裝在一個結構體內 ,對外界來
說不可見的 并把作用域鏈賦值給一個特殊的內部屬性([scope])。然后使用this.arguments(arguments在全局環境中不存在)和其他命名參數的值來初始化函數的活動對象(activation
object)。當前執行環境的變量對象始終在作用域鏈的第0位
例子function a(){
var a;
function b(){
return a
}
return b
}
var fun=a()
fun()
在JS運行上面機制 a函數作用鏈(scope chain ) b作用域鏈(b是內部函數)[scope chain] 會生成執行上下文變量 當代碼在一個環境中執行時,會創建變量對象的一個作用域鏈。作用域鏈的用途是保證對執行環境(執行上下文)有權訪問的所有變量和函數的有序訪問。
變量對象(VO):變量對象即包含變量的對象,變量對象我們無法訪問,除此之外和普通對象沒什么區別。變量對象存儲了在上下文中定義的變量和函數聲明
活動對象(AO):是在進入函數執行
環境時刻被創建的,它通過函數的 arguments 屬性初始化。變量對象和活動對象的關系
未進入執行階段之前,變量對象(VO)中的屬性都不能訪問,只是聲明但是進入執行階段
之后,變量對象(VO)轉變為了活動對象(AO),里面的屬性都能被訪問了,然后開始進行執行階段的操作。它們其實都是同一個對象,只是處于執行環境的不同生命周期。AO 實際上是包含了 VO 的。因為除了 VO 之外,AO
還包含函數的 parameters,以及 arguments 這個特殊對象。也就是說 AO 的確是在進入到執行階段的時候被激活,但是激活的除了 VO 之外,還包括函數執行時傳入的參數
和 arguments 這個特殊對象。
四、 JavaScript閉包
在js私有函數對外部函數產生引用或者變量依賴就會產生閉包 通俗的講函數是可以嵌套函數的,內部function可以訪問外部function的變量;通過引用訪問函數內的函數,實現內存的保留;訪問函數內的函數,突破變量作用域限制
var a=function(){
var a的變量
function b(){
a++;
}
return b}
var s=a()
1、信息保留就是引用存在,空間不會因為函數(內部函數)銷毀,而消失,
c.add1();
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。