1. 程式人生 > 其它 >【閱文筆記】函式作用域【你不知道的JavaScript(上)】

【閱文筆記】函式作用域【你不知道的JavaScript(上)】

技術標籤:筆記js函式作用域

函式作用域

一、函式作用域

我們已經知道, 在任意程式碼片段外部新增包裝函式, 可以將內部的變數和函式定義“隱藏” 起來, 外部作用域無法訪問包裝函式內部的任何內容

看下面程式碼:

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 變數名被隱藏在自身中意味著不會非必要地汙染外部作用域

二、匿名和具名

函式表示式你最熟悉的場景可能就是回撥引數了,例如: