什麼是作用域
作用域是在運行代碼是代碼中的默寫特定部分中的變量,函數和對象的可訪問性,變量不是在所有地方都可以使用的,而這個變量的使用範圍就是作用域。
局部作用域,函數內部
function fn(){
var a = 10;
console.log(a); //10
}
fn();
console.log(a);// 報錯:a is not defined at
函數中的變量a屬於局部變量 所以只能被局部所打印 而在函數外去打印a會顯示報錯圖如下:
全局作用域,不在任何函數中
var a = 20;
function(){
var a =10;
console.log(a)//20
}
fn();
console.log(a)//10
函數全局變量定義a爲20,局部變量定義爲10,所以第一次函數外打印a是得不到局部變量中的a=10;圖爲一下
所以說得函數外的打印 是獲取不了局部中定義的值得,全局不能訪問局部。
var b = 30;
var a = 20;
function fn(){
var a = 10;
console.log(a);//10
console.log(b);//30
}
fn()
console.log(a);//20
在局部打印全局變量的變量是可以的到該變量的;比如25行代碼得到變量b的值。
圖中24行爲局部變量a的值,25行爲全局變量b的值,得出局部變量是可以使用全局變量,而全局變量無法得到局部變量的值。
局部可以拿到全局。
因爲有了作用域,所以變量的使用就有了規則
1.訪問規則
想要獲取某個變量的值,叫訪問。
當前作用域->上一級作用域->…->全局作用域
找到即停止
到全局未找到,直接報錯(該變量 is not defined)
var a = 10;
function fn(){
function fn1(){
console.log(a);
}
fn1();
console.log(a)
}
fn();
這裏的a未定義在函數中,所以48行打印a在局部中找不到a的值,就往他的上級去尋找 所以 48行51行打印a都爲10。
假如在fn1函數中定義了變量a的值爲20;那麼48行打印的a就爲20,因爲就近原則,所以他會選擇最近的值。圖如下。
如上圖沒有變量a的賦值,呢麼47行打印a就會變成 a is not defined
at 。報錯 因爲整個全局都找不到變量a。
1.賦值規則
當你想給一個變量賦值的時候,那麼就先要找到這個變量,再給他賦值
當前作用域->上一級作用域->…->全局作用域
找到即停止
到全局未找到,直接定義爲全局並賦值
fn(); // 輸出結果fn
function fn(){
var b = 30;
function fn1(){
console.log(b);
b = 40; // b會往上一級尋找已經聲明的同名變量,並賦值,直到全局作用域時還沒找到,則會成爲window的屬性
}
fn1();
console.log(b); // 輸出b
}
這裏的36行的打印b,但是在局部中找不到b的值,所以向上一級作用域去尋找 找到了b的值爲30,而fn1函數中的b在運行後唄重新賦予了值爲40,所以40行的b爲重新賦予的值 也就是爲40。
總結:
作用域的訪問機制:父不能拿子子可以拿父。
當使用var聲明變量時,程序會將這個聲明提升到 區域 頂端,在原本=號的位置,正常賦值。
函數的聲明也存在提升,這個提升,是整體提升,可以認爲既提前聲明,又提前賦值。
新人初來,有很多欠缺需要大家多多指教,逆疫而戰大家加油_