簡體   English   中英

為什么第一個console.log()打印未定義的值,但是第二個卻轉換了值

[英]why does the first console.log() print undefined values but second one has transformed values

為什么第一個console.log()打印未定義的值,而第二個卻轉換了值? 我知道它必須與功能范圍做一些事情,但不能得到它

 var array = [1,2,3,4,5,7]; function incrementByOne(arr) { arr = arr.map(function(value, index, array){ arr[index] = arr[index] +1; }); console.log(arr); } incrementByOne(array); console.log(array); // [undefined, undefined, undefined, undefined, undefined, undefined] // [2, 3, 4, 5, 6, 8] 

我也注意到第一個console.log()知道要迭代多少次,但是值發生了什么...

js bin鏈接

您需要從map內部的函數返回增量值。 使用return arr[index] +1另外,您現在還需要返回使用map形成並存儲在arr中的新數組。

 var array = [1,2,3,4,5,7]; function incrementByOne(arr) { //contains array reference arr = arr.map(function(value, index, array){ return value +1; }); //now arr contains a new array and doesn't refer to passed array anymore. console.log(arr); return arr; } array = incrementByOne(array); console.log(array); // [undefined, undefined, undefined, undefined, undefined, undefined] // [2, 3, 4, 5, 6, 8] 

如果您不想返回,則可以使用forEach(),因為在這種情況下,arr將始終引用傳遞的數組。 區別在於map返回一個新數組。

 var array = [1,2,3,4,5,7]; function incrementByOne(arr) { //contains array reference arr.forEach(function(value, index){ arr[index] = value +1; }); //arr still refers to the passed array. console.log(arr); } incrementByOne(array); console.log(array); // [undefined, undefined, undefined, undefined, undefined, undefined] // [2, 3, 4, 5, 6, 8] 

這里發生了幾件事:

  1. 傳遞給.map函數的回調應返回帶有return關鍵字的值。 如果您沒有從回調中返回值,則默認的返回值是不確定的。 這就是為什么當您使用第一個console.log記錄時,您在incrementByOne中定義的“ arr”數組內部僅具有未定義值的原因。 我認為您真正想做的只是在回調內部返回值+ 1。

  2. 您在這里犯了一個經典的按值傳遞按引用傳遞錯誤; 這是每個人第一次學習JS時都會犯的一個錯誤。 我建議您查看此類帖子。 簡而言之,在您的.map回調內部,您正在對傳遞給incrementByOne的數組進行突變,該數組與您在第二個console.log中注銷的數組相同; 這就是為什么值似乎已正確增加的原因。

 var array = [1,2,3,4,5,7]; function incrementByOne(arr) { arr = arr.map(v => v + 1); console.log(arr); } incrementByOne(array); console.log(array); // [undefined, undefined, undefined, undefined, undefined, undefined] // [2, 3, 4, 5, 6, 8] 

好吧,以上所有答案都是正確的,但他們錯過了這里最重要的要點。 JavaScript中有一個稱為共享調用的概念。

考慮以下代碼:

 var num= 3; var json = {myValue : '10'}; var json2 = {myValue : '100'}; function callBySharing(a,b,c){ a = a + 37; b = {myValue : 'new value'}; c.myValue = 'new Value'; } callBySharing(num,json,json2); console.log(num);//3 *UNCHANGED* console.log(json.myValue);//10 *UNCHANGED* console.log(json2.myValue);//'new Value' *CHANGED* 

因此,您正在做的事情與json.myvalue中發生的事情相同; 您正在嘗試更新整個對象並將其替換為新值。 因此,對代碼進行一個非常簡單的更改即可為您完成此操作:

 var array = [1,2,3,4,5,7]; function incrementByOne(arr) { arr.map(function(value, index, array){ arr[index] = arr[index] +1; }); console.log(arr); } incrementByOne(array); console.log(array); 

我只是將arr = arr.map()....替換為arr.map().....

這是什么,它將功能更改為json2.myValue示例案例。

2:2的區別是什么?JS使您可以更新對象中的項目,而不是整個對象。通過對代碼進行上述更改,您將更新arr的單個值,而不是用新值替換整個對象。 我只有在與SO混淆時才從SO中學習到這一概念。 所以我鏈接了這篇文章( JavaScript是通過引用傳遞還是通過值傳遞語言?

希望這可以幫助!

暫無
暫無

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

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