js作用域鏈的理解
從事web開發工作的,難免會聽到作用域鏈這個詞,如果你還是似懂非懂的話,那麼看這篇文章就足夠了。要理解什麼是作用域鏈,那必須先理解變數作用域,函式作用域,下面我來一一介紹。
變數作用域
在js中,變數分為全域性變數和區域性變數。全域性變數的作用域是全域性的,在任意地方都是被定義的。而區域性變數可以是函式的引數、函式內定義以及{}內(ES6語法)定義,如果區域性變數與全域性變數重名的話,會優先取區域性變數。下面我們來看看例子:
引用全域性變數例子:
var num = 1; //定義一個全域性變數 function func(){ console.log(num); //這裡引用了全域性變數 } func(); //輸出:1
同名變數優先區域性變數例子:
var num = 1;//定義一個全域性變數 function func(){ var num = 2;//宣告區域性變數時一定要使用var,否則直譯器會將該變數當做全域性物件window的屬性 console.log(num);//這裡引用了局部變數 } func();//輸出:1
函式作用域
變數在宣告它們的函式體以及這個函式體內的任意函式體都是定義的,請看例子:
function func(){ var num = 1; console.log(num);//輸出:1 function func1(){ console.log(num);//輸出:1 } func1(); } func();
作用域鏈
把函式自身的本地變數放在最前面,把自身的父級函式中的變數放在其次,把再高一級函式中的變數放在更後面,以此類推直至全域性物件為止,當函式中需要查詢一個變數的值的時候,js直譯器會去從作用域鏈查詢,從最前面的本地變數中先找,如果沒有找到對應的變數,則到下一級的鏈上找,一旦找到了變數,則不再繼續,如果找到最後也沒有找到需要的變數,則直譯器返回undefined。請看例子:
例子1:
var num = 1; function func(){ var num = 2; function func1(){ var num = 3; console.log(num);//輸出:3先找函式自身的本地變數 } func1(); } func();
例子2:
var num = 1; function func(){ var num = 2; function func1(){ console.log(num);//輸出:2先找函式自身的本地變數,再找父級函式中的變數 } func1(); } func();
例子3:
var num = 1; function func(){ function func1(){ console.log(num);//輸出:1先找函式自身的本地變數,再找父級函式中的變數,然後再找到全域性物件的變數 } func1(); } func();
例子4:
function func(){ function func1(){ console.log(num);//輸出:undefined先找函式自身的本地變數,再找父級函式中的變數,然後再找到全域性物件的變數,還是沒找到就返回undefined } func1(); } func();