JavaScript 採用 語法作用域,
語法作用域又分為 動態作用域 和 靜態作用域
靜態作用域:
當我們在寫一個函式時,語法解析器就確定了變數的作用域,且不會再改變。
(JavaScript 屬於靜態作用域)
動態作用域:
變數的作用域在函式調用時才決定。
如果作用域(函式)內有需要一些變數,但作用域內沒有時,就會向外查找,若有找到就會拿來取用。
範例 1
var value = 1;
function fn1() {
console.log(value);
}
function fn2() {
var value = 2;
fn1();
}
fn2(); //答案是1
解析執行順序
var value = 1;
fun2();
var value = 2; // 此值只會在 fun2()內
fun1(); // 向外查找到 1
// 如果是動態作用域,答案就是 2
一個函式的執行,就會產生一個屬於自己的執行環境,而執行環境有限制作用域 的功用,
並且會有自己的 this。
window , global
this (等同於 window 或 global )
範例 1
function sayHi(name){
var greeting = 'hi';
return greeting + ''+ name;
}
function doSomething(){
var mom = '老媽';
console.log(1, sayHi(mom));
}
doSomething(); // 1, hi 老媽
執行環境順序:
全域環境 → doSomething()
執行環境 // 傳入老媽給sayHi()
→ sayHi()
執行環境 // 回傳 'hi 老媽'
結果就會是 1, hi 老媽。
執行環境是一層一層堆疊起來的,跟函式宣告沒有關連性,而是與呼叫的位置有關係。
範例 2
function openTheDoor(num) {
return '開第 ' + num + ' 扇門';
}
function openDoors() {
openTheDoor(1);
for (var i = 2; i < 5; i++) {
openTheDoor(i);
}
}
openDoors();
執行順序:openDoors();
openTheDoor(1);
// 傳入1 回傳 '開第 1 扇門'
for迴圈 i=2 // 傳入2 回傳 '開第 2 扇門'
for迴圈 i=3 // 傳入3 回傳 '開第 3 扇門'
for迴圈 i=4 // 傳入4 回傳 '開第 4 扇門'
for迴圈 i=5 // 不符合條件 i < 5, 離開迴圈
函式沒有透過呼叫是不會執行的,而執行環境可透過不斷呼叫產生。