簡體   English   中英

從函數中重新分配全局變量

[英]Reassigning a global variable from within a function

在關於JavaScript對象的(Udacity)課程的一部分中,它說因為基元是不可變的,所以對函數內部的參數所做的任何更改都會有效地創建該函數的局部副本,而不會影響它之外的基元。 這是提供的示例:

function changeToEight(n) {
  n = 8; // whatever n was, it is now 8... but only in this function!
}

let n = 7;

changeToEight(n);

console.log(n); // 7

但是,如以下示例所示,您可以在函數內更改分配給全局變量的值(只要變量名稱不作為參數傳遞):

let counter = 1;

function changeCounter() {
  counter = 2;
}

changeCounter();
console.log(counter); // 2

如果原語是不可變的,為什么變量在后一個例子中是可變的? 本課程中提供的示例實際上與原語不是不可變的有關,還是因為函數中的變量名稱與傳遞給函數的參數名稱相同?

值是不可變的,而不是變量。 變量可以是常量,但這是一個不同的主題。

價值不變性意味着你不能做1 = 2'hello' = 'world'因為它沒有意義(如果你有原始值)。

另一方面,對象是可變的,因此您可以更改其內部結構。

obj = {
  name: 'John'
};
obj.name = 'Sue';

但是你可以通過使用Object.freeze(obj)使對象不可變(只是要小心因為它只產生一個淺的不變性)。


你的意思是一個constant變量 - 無法重新分配的變量。 所以你不能做類似的事情

const x = 1;
x = 2;

但同樣,如果它是一個對象,則可以更改存儲在常量變量中的值的內部狀態(對象屬性的更改不計入重新分配)。


在您的第一個示例中,它實際上與原始值或對象無關。 即使它是一個對象,也會發生同樣的事情。 重新分配是產生本地副本的。

 function changeToEight(n) { n = [8]; } let n = [7]; changeToEight(n); console.log(n); 

只有對該對象的就地更改才會產生具有相同名稱的新局部變量(例如: Array.prototype.push方法,如果我們考慮一個數組)。

 function changeToEight(n) { n.push(8); } let n = [7]; changeToEight(n); console.log(n); 


你的第二個例子是不同的,因為函數changeChouter沒有自己的局部變量n 根據范圍解析規則,引用時的變量首先在本地范圍中搜索,如果失敗,則在下一個封閉范圍中搜索它們。

該變量n ,因為它不是你的函數的本地變量,在changeChouter的封閉范圍中搜索,在這種情況下,它是找到它的全局范圍。 這意味着您要重新分配該全局變量。

所以你的代碼基本上相當於

 let counter = 1; counter = 2; console.log(counter); 

function changeToEight(n)

由於參數,將局部變量賦值為n ,並且您將changeToEight函數中的局部變量賦值為8.它不會影響全局n變量。 如果你做得像

 function changeToEight(m) { n = 8; // global variable n is now 8...! but local variable m is 7..! } let n = 7; changeToEight(n); console.log(n); // 8 cool..! 

一切都會如預期的那樣......

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM