const words = ['I', 'am', 'a', 'student'];
const x = words[0];
const x = words[1];
以上在執行時,第3行會出現錯誤
SyntaxError: Identifier 'x' has already been declared,
說x已經被宣告過了。
但如果是下列的程式碼就不會有問題,
const words = ['I', 'am', 'a', 'student']
for (let i = 0; i < 4; i++) {
const x = words[i];
}
可是明明我在for迴圈內做了4次x的重複宣告,
為什麼不會出現x已經被宣告過了的錯誤訊息?
你可以簡單理解,在 for 迴圈中的 {} 裡,宣告的 變數/常數 的生命期,就在當下那一趟。
跑下一趟時,剛剛上一趟所宣告的 變數/常數 已經不存在了。
如果想要 變數/常數 的生命期存在於迴圈所有趟裡,那就要在 {} 之前宣告。如此而已。
在 for 裡的 const 宣告作用域只侷限在 for 迴圈裡,不會影響到外面的宣告。因此看起來是重複宣告,實際上兩者並不相干,所以不會跳錯誤。
你要先有區域變數的觀念。
javascript 有個非常奇特的現象。
大多數的{}包起來的。都會被視為不同的區域。
而變數定義宣告,理論上只能被定義一次。
重覆定義就會報錯。
但在FOR裏面。因為是被{}包起來的關係。
所以會被視為不同區域。
自然就可以各自被定義。
for (let i = 0; i < 4; i++) {
const x = 3;
}
您是指在上列的for迴圈中,const x = 3;
分別在4個區域中被宣告和定義嗎?
如果如此,那是否代表每一次執行const x = 3;時,
皆會佔用不同的記憶體位址呢?
但我把它改以下列C語言後,得到的記憶體位址皆是相同的 @@?
for (int i = 0; i < 4; i++) {
int x = 3;
printf("變數x的位址 = %p\n", &x);
}
一開頭我有先跟你說。
javascript是很奇特的語言。
它跟一般後端程式語言的認知會有些不同。
常常不小心就會進入迷霧的世界裏。
有時會搞到懷疑人生。
認真來說,學習一下ES6的寫法。會比較不容易陷入迷霧
畢竟
for (let i=0; i<items.length; i++) {
copy.push(items[i])
}
會不清楚{}之間的區域認知問題。
但同樣的東西改成ES6寫法
items.forEach(function(item){
copy.push(item)
});
至少這樣還能清楚明白閉包的情況。也不容易被誤解。
for的scope,其實從小括弧就開始算:
for (const i of items) {
const qt = i.qt * 5;
}
之類的。