作用域
全局作用域 global
(1)最外層函數和在最外層函數外的變量擁有全局作用域
var i=1;
function a(){
var aw="qw";
console.log(aw);
function ba(){
var qq="aaa";
}
}
console.log(i);
condole.log(aw);
a();
//1
//Uncaght ReferenceError : aw is not defined(...)
//qw
(2)所有沒有聲明變量都自動聲明擁有全局作用域
function c(){
o="qw";
function ba(){
p="aaa";
}
ba();
}
c();
console.log(o);
console.log(p);
// qw
// aaa
(3)一般情況下,window下所有的屬性默認擁有全局作用域,如:windows.onload,window.scroll等
局部作用域
與全局作用域相反,局部作用域只作用于某些代碼片段內,只在內部可用
function ew(){
var e=2;
function q(){
var s=2,w=3;
console.log(s);
var d=s+w;
}
q();
console.log(d);
}
undefined
ew();
// 2
// Uncaught ReferenceError: d is not defined(…)
作用域鏈
在JavaScript中,函數也是對象,實際上,JavaScript里一切都是對象。函數對象和其它對象一樣,擁有可以通過代碼訪問的屬性和一系列僅供JavaScript引擎訪問的內部屬性。其中一個內部屬性是[[Scope]],由ECMA-262標準第三版定義,該內部屬性包含了函數被創建的作用域中對象的集合,這個集合被稱為函數的作用域鏈,它決定了哪些數據能被函數訪問。
function fo(){
var a=3;
}
這里函數文調用之前,作用域如圖
作用域鏈前
執行此函數時會創建一個稱為“運行期上下文”的內部對象,運行期上下文定義了函數執行時的環境。每個運行期上下文都有自己的作用域鏈,用于標識符解析,當運行期上下文被創建時,而它的作用域鏈初始化為當前運行函數的[[Scope]]所包含的對象。
這些值按照它們出現在函數中的順序被復制到運行期上下文的作用域鏈中。它們共同組成了一個新的對象,叫“活動對象”,該對象包含了函數的所有局部變量、命名參數、參數集合以及this,然后此對象會被推入作用域鏈的前端,當運行期上下文被銷毀,活動對象也隨之銷毀。新的作用域鏈如下圖所示:
作用域鏈后