據我了解,陣列和物件都是基于記憶體地址的參考傳遞,所以如果我創建另一個變數并指向陣列/物件,并改變任何值,另一個值也應該改變。
但是,我不太明白它在這里是如何作業的。我指向 array1 并將 array1 修改為空,為什么 anotherArray 的值沒有改變?
var array1 = [1,2,3,4,5,6,7]; // Created array
var anotherArray = array1; // Referenced array1 by another variable
array1 = []; // Empty the array
console.log(anotherArray); // Output [1,2,3,4,5,6,7]
我可以理解下面的例子為什么 anotherArray 變成 [] 空,因為它是通過參考傳遞的,但是為什么 anotherArray 仍然輸出 [1,2,3,4,5,6,7] 上面的?
var array1 = [1,2,3,4,5,6,7]; // Created array
var anotherArray = array1; // Referenced array1 by another variable
array1.length = 0; // Empty the array by setting length to 0
console.log(anotherArray); // Output []
謝謝你。
uj5u.com熱心網友回復:
分配給變數永遠不會改變變數先前作為值的物件。
物件——比如陣列——只有在你改變它們時才會改變,要么通過呼叫執行此操作的方法,要么通過設定屬性。
這是您的第一個腳本的可視化:
var array1 = [1,2,3,4,5,6,7] 結果如下:
array1
↓
┌──────┬───┬───┬───┬───┬───┬───┬───┐
│length│ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │
├──────┼───┼───┼───┼───┼───┼───┼───┤
│ 7 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │
└──────┴───┴───┴───┴───┴───┴───┴───┘
在var anotherArray = array1我們有了這個之后:
array1
↓
┌──────┬───┬───┬───┬───┬───┬───┬───┐
│length│ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │
├──────┼───┼───┼───┼───┼───┼───┼───┤
│ 7 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │
└──────┴───┴───┴───┴───┴───┴───┴───┘
↑
anotherArray
然后array1 = []將創建一個新陣列:所以現在有兩個陣列。它還array1參考了新創建的陣列:
array1
↓
┌──────┐
│length│
├──────┤
│ 0 │
└──────┘
┌──────┬───┬───┬───┬───┬───┬───┬───┐
│length│ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │
├──────┼───┼───┼───┼───┼───┼───┼───┤
│ 7 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │
└──────┴───┴───┴───┴───┴───┴───┴───┘
↑
anotherArray
在第二個腳本中,對length屬性(實際上是一個 setter)的賦值將改變陣列。沒有創建新陣列,值 1,2,3,4,5,6,7 丟失:
array1
↓
┌──────┐
│length│
├──────┤
│ 0 │
└──────┘
↑
anotherArray
uj5u.com熱心網友回復:
對于您的第一個示例,您實際上是將 array1 重新分配為一個空陣列(現在它們指向記憶體中的 2 個不同陣列),因此 anotherArray 保持不變。
var array1 = [1,2,3,4,5,6,7]; // Created array
var anotherArray = array1; // Referenced array1 by another variable
array1 = []; // Empty the array
console.log(anotherArray); // Output [1,2,3,4,5,6,7]
在這種情況下,您實際上是通過將陣列的長度分配為 0 來修改陣列。由于 array1 參考了它,因此它也會影響他,因為它們參考了記憶體中的相同陣列。
var array1 = [1,2,3,4,5,6,7]; // Created array
var anotherArray = array1; // Referenced array1 by another variable
array1.length = 0; // Empty the array by setting length to 0
console.log(anotherArray); // Output []
uj5u.com熱心網友回復:
線
array1 = [];
不修改之前分配給 的陣列物件array1。它為變數分配一個新的(空)陣列;這不像對分配給 的物件呼叫操作array1。
換句話說,假設array1是參考先前分配的陣列物件 ( [1,2,3,4,5,6,7])的唯一變數。執行該行(順便說一句,這是一條陳述句)后,您丟失了先前分配的陣列;它會在一段時間后被垃圾收集。這都是因為這里使用了賦值運算子,并且它們的操作語意是在 JavaScript 中定義的。
更重要的是,您在這里濫用了按參考傳遞的概念(又名按參考呼叫);這是一個與如何將值傳遞給函式呼叫(或子例程/程序,如果您更喜歡談論子例程/程序而不是函式)的引數有關的概念。
uj5u.com熱心網友回復:
在第一種情況下,您實際上并未更新由 array1 參考的物件。您正在替換變數 name 下的值array1。anotherArray指向記憶體中的值,該值是array1.
在第二個示例中,您實際上是在更新array1和anotherArray都指向的基礎值
uj5u.com熱心網友回復:
在賦值運算子, 中a = x,右側被計算為運算式( x) 并將結果值賦給a。
這意味著a永遠不會“參考”x。
因此兩者a = b和a = [] 結果都a被重新分配。如果右側是變數(即被評估)或空陣列文字,則無關緊要:
var b = [1,2,3] // create and assign array #1
var a = b
// ^— a is assigned the result of evaluating b
// after this assignment a and b “refer to” (read: evaluate to) the same object..
// b -> [1,2,3] #1
// a -> [1,2,3] #1
a.pop()
// ^— modify array object (a.length = 0 would empty the array)
// ..and since a and b refer to THE SAME ARRAY..
// b -> [1,2] #1
// a -> [1,2] #1
var a = [] // create and assign array #2
// ^— a is assigned the result of evaluating []
// after re-assignment both a and b refer to different array objects..
// (the assignment did not alter mutate the original array)
// b -> [1,2] #1
// a -> [] #2
a.push(3)
// ^— modify array object
// ..and since a and b refer to DIFFERENT ARRAYS..
// b -> [1,2] #1
// a -> [3] #2
呼叫函式的作業方式與賦值完全相同,并且在 JavaScript 中沒有“按參考呼叫”。的值,從結果運算式的求作為引數被提供。JavaScript 具有Call by (Object) Sharing語意。
tldr:這里沒有必要討論 Javascript 中的“參考”,因為它們會增加不必要的混淆,甚至在規范中都沒有定義(以這種方式)!
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/386034.html
標籤:javascript 数组 目的
上一篇:如何過濾具有多個值的陣列?|反應
