【閱文筆記】函式作用域【你不知道的JavaScript(上)】
阿新 • • 發佈:2020-12-16
函式作用域
一、函式作用域
我們已經知道, 在任意程式碼片段外部新增包裝函式, 可以將內部的變數和函式定義“隱藏” 起來, 外部作用域無法訪問包裝函式內部的任何內容
看下面程式碼:
var a = 2;
function foo() { // <-- 新增這一行
var a = 3;
console.log( a ); // 3
} // <-- 以及這一行
foo(); // <-- 以及這一行
console.log( a ); // 2
它並不理想,首先,必須宣告一個具名函式 foo(), 意味著 foo 這個名稱本身“汙染” 了所在作用域(在這個例子中是全域性作用域)。 其次, 必須顯式地通過函式名(foo()) 呼叫這個函式才能執行其中的程式碼
如果函式不需要函式名
(或者至少函式名可以不汙染所在作用域), 並且能夠自動執行
,這將會更加理想
。
JavaScript 提供了能夠同時解決這兩個問題的方案
var a = 2;
(function foo(){ // <-- 新增這一行
var a = 3;
console.log( a ); // 3
})(); // <-- 以及這一行
console.log( a ); // 2
首先, 包裝函式的宣告以 (function...
而不僅是以function… 開始。這函式會被當作函式表示式
而不是
一個標準的函式宣告
來處理。
區分
函式宣告和表示式最簡單的方法
是看 function 關鍵字出現在宣告中的位置
(不僅僅是一行程式碼, 而是整個宣告中的位置)。 【如果 function 是宣告中的第一個詞, 那麼就是一個函式宣告, 否則就是一個函式表示式】
函式宣告和函式表示式
之間最重要的區別
是它們的名稱識別符號將會繫結在何處
比較前面兩個程式碼片段:第一個片段中 foo 被繫結在所在作用域中
, 可直接通過foo() 呼叫它
。 第二個片段中 foo 被繫結在函式表示式自身的函式中
而不是所在作用域中
換句話說, (function foo(){ … }) 作為函式表示式意味著 foo 只能在 … 所代表的位置中被訪問, 外部作用域則不行。 foo 變數名被隱藏在自身中意味著不會非必要地汙染外部作用域
二、匿名和具名
函式表示式你最熟悉的場景可能就是回撥引數了,例如: