[英]what is local scope in JavaScript? How is local scope different to function scope?
我對編碼很陌生,並且對局部作用域與函數作用域和塊作用域之間的區別感到困惑。
我知道全局作用域是在函數之外聲明一個變量,以便可以在任何地方訪問它。 函數作用域是指可以在函數內的任何位置訪問變量,而塊作用域是指可以在一組大括號內訪問變量,例如{let a = block scope}
,
不過,我很困惑。 什么是局部作用域? 局部作用域和函數作用域一樣嗎?
任何幫助都感激不盡
“局部作用域”是任何非全局作用域的統稱,因此它包括函數作用域和塊作用域(和模塊作用域)。
過去 JavaScript 只有函數作用域和全局作用域。 作為ES2015的,它也具有用於塊范圍let
, const
,和class
聲明,以及“模塊范圍”(為一個模塊的頂層范圍),並for
范圍(細節如下)。
下面是一個例子:
// Assume this code is not in a module and is at the top level
let a; // Global scope
function example() {
let b; // function scope (a kind of local scope)
for (let n = 0; n < 2; ++n) { // `n` is in local scope for the `for` (a kind of local scope)
let c = n * 2; // block scope (a kind of local scope)
}
// This is a freestanding block, they don't *have* to be attached to anything
{
let d; // block scope (a kind of local scope)
}
}
這將是一樣的,如果這是一個模塊中的不同之處在於let a
不會在全球范圍內,這將是在模塊范圍內。
在for
循環初始值設定項中包含let
聲明的范圍與for
具有的任何塊的附加范圍並不完全相同,這可能是值得的。 前者是后者的父作用域,有時for
沒有附加塊:
for (let n = 0; n < 0; ++n)
console.log(n);
上述n
的范圍不明顯。 它的范圍僅限於for
循環,但以一種非常有趣的方式:為每次循環迭代創建一個新的n
。 所以對於第一次交互,有一個n
的值為0
。 然后,創建一個新的n
,獲取舊n
值的副本,然后遞增; 然后新的n
用於下一次循環迭代。 這對於循環中的閉包很方便。
這是個好問題。 在大多數情況下,函數作用域是局部作用域。
但是,請考慮以下代碼:
function foo(){
const sum = 0
someArray.forEach(function(item){
var plusOne = item + 1
sum = sum + 1
})
}
這個函數包含一個定義自己作用域的內部函數(稱為閉包)。 當內部函數正在執行時, plusOne
在本地范圍內。 sum
不在本地范圍內,但也不在“全局”范圍內; 它在其父級的范圍內。 (你會在 Chrome Dev Tools 中看到它被描述為“閉包”作用域。)作用域是嵌套的,所以你的內部函數/閉包可以查看和修改父作用域中的變量(在這種情況下為sum
)。
如果您使用的是 CommonJS/ES6 模塊,還有另一種可能性。 這可能是一個文件:
var foo = 1
export function bar() {
return foo
}
您可以編寫此(ES6)代碼來訪問bar
:
import {bar} from "thefile"
console.log(bar())
你不能寫這個代碼:
import {foo} from "thefile"
foo
看起來是“全局的”-ish,但它實際上是模塊本地的,因此僅在該模塊的范圍內。 它沒有導出,因此在該模塊之外無法訪問。
(旁白:“轉譯器”會將為一個平台/版本編寫的 JavaScript 轉換為另一個平台/版本。因此,例如,像我上面寫的那樣將現代 ES6 轉譯為最低公分母是很常見的,例如 web瀏覽器。瀏覽器一般不支持模塊,因此轉譯器會將原始模塊代碼包裝在一個函數中,從而將“模塊范圍”轉換為“函數范圍”。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.