iT邦幫忙

2024 iThome 鐵人賽

DAY 13
0

作用域(Scope)

作用域是指變數可被訪問的範圍。在 JavaScript 中,作用域主要有以下幾種:

1.全域作用域(Global Scope): 變數在整個程式中都可被訪問。
2.函數作用域(Function Scope): 變數只在函數內部可訪問,函數外部無法訪問。
3.塊級作用域(Block Scope): 使用'let'和'const'定義的變數只在其所在的塊(例如'if'、'for'等語句)中可訪問。(ES6 引入)

var globalVar = "我是全局變量";

function exampleFunction() {
    // 函數作用域
    var functionVar = "我是函數作用域變量";
    
    if (true) {
        // 塊級作用域 (使用 let)
        let blockVar = "我是塊級作用域變量";
        var functionVarInBlock = "我也是函數作用域變量";
        
        console.log(globalVar);  // 輸出: 我是全局變量
        console.log(functionVar);  // 輸出: 我是函數作用域變量
        console.log(blockVar);  // 輸出: 我是塊級作用域變量
    }
    
    console.log(functionVarInBlock);  // 輸出: 我也是函數作用域變量
    // console.log(blockVar);  // 這行會報錯: blockVar is not defined
}

exampleFunction();
console.log(globalVar);  // 輸出: 我是全局變量
// console.log(functionVar);  // 這行會報錯: functionVar is not defined

** 值得注意的是,使用'var'聲明的變量'functionVarInBlock'雖然在塊內定義,但實際上是函數作用域的。

閉包(Closure)

閉包是一種函數,他能夠“記住”並訪問其外部作用域的變數,即使在其外部函數已經執行完畢的情況下。這是由於 JavaScript中的函數作用域和作用域鏈的特性。

特點:

  • 保持外部作用域的變數: 閉包可以存取其創建時的作用域中的變數,即使外部函數已經返回。
  • 封裝狀態: 閉包可以被用來創建私有變數,這樣可以避免全域變數的污染。
  • 高階函數: 閉包常用於高階函數中,例如回調函數或事件處理函數。
function createCounter() {
    let count = 0;  // 私有變量
    
    return function() {
        count++;  // 訪問並修改閉包中的變量
        return count;
    };
}

const counter1 = createCounter();
const counter2 = createCounter();

console.log(counter1());  // 輸出: 1
console.log(counter1());  // 輸出: 2
console.log(counter2());  // 輸出: 1
console.log(counter1());  // 輸出: 3

// 模擬私有方法
function createPerson(name) {
    let age = 0;  // 私有變量
    
    function growOlder() {  // 私有方法
        age++;
    }
    
    return {
        getName: function() { return name; },
        getAge: function() { return age; },
        haveBirthday: function() {
            growOlder();
            console.log(name + " is now " + age + " years old.");
        }
    };
}

const person = createPerson("Alice");
person.haveBirthday();  // 輸出: Alice is now 1 years old.
person.haveBirthday();  // 輸出: Alice is now 2 years old.
console.log(person.getAge());  // 輸出: 2
// console.log(person.age);  // 這行會輸出 undefined, 因為 age 是私有的

在這個例子中有三個要注意的事:
1.'createCounter'函數返回一個新的函數,這個新函數可以訪問和修改'count'變量。
2.每次調用'createCounter'都會創建一個新的閉包,有自己的'count'變量。
3.'createPerson'函數展示了如何使用閉包來創建私有變量和方法。


上一篇
d12 DOM操作
下一篇
d14 異步編程(上)
系列文
javascript基礎自學及各工具應用了解30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言