对javascript上的数组感到困惑

Seb*_*vez 3 javascript arrays

我想基于另外两个数组创建下一个数组:

array1 = ['a', 'b']
array2 = [1,2,3]
Run Code Online (Sandbox Code Playgroud)

我想创建下一个数组

newArray = [['a',1], ['a',2], ['a',3], ['b',1], ['b',2], ['b',3]]
Run Code Online (Sandbox Code Playgroud)

这是我的代码:

    var test1 = ['a', 'b'];
    var test2 = [1,2,3], arr1 = [], arr2 = [];

    for(var i = 0; i < test1.length; i++){
       arr1 = [];
       arr1.push(test1[i]);
      for(var x = 0; x < test2.length; x++){
        if(arr1.length > 1)
        	arr1.pop();
        arr1.push(test2[x])
        arr2.push(arr1);
        
      }
    }

console.log("arr1:",JSON.stringify(arr1), "arr2:" ,JSON.stringify(arr2));
Run Code Online (Sandbox Code Playgroud)

但它返回第二个数组的最后一个元素.

[['a',3], ['a',3], ['a',3], ['b',3], ['b',3], ['b',3]]
Run Code Online (Sandbox Code Playgroud)

为什么会这样?

the*_*ian 5

关于数组长度的所有其他答案以及类似的事情都是不对的.你得到的唯一原因3(或者最后一个值/长度是什么)是因为数组是引用的,而functions不是for-loops创建词法范围.这是你听说'功能是javascript中的一等公民'的原因之一.这是一个经典的例子,并且经常在采访中,用来惹恼那些不熟悉javascript中的范围如何真实行为的开发者.有一些方法可以修复它,包括在函数范围内包装循环内部,并传入索引,但我想建议一个更"以javascript为中心"的方法,那就是解决函数问题.

请参阅此示例(顺便提一下,这也是实现目标的明确方法.)

var test1 = ['a', 'b'];
var test2 = [1,2,3];
    
// this will iterate over array 1 and return
// [[ [a,1],[a,2],[a,3] ],[ [b,1],[b,2],[b,3] ]]
var merged = test1.map(function(item1){
    return test2.map(function(item2){
        return [item1, item2];
    });	
  });

//this is a slick way to 'flatten' the result set
var answer = [].concat.apply([],merged )
    
console.log(answer) //this is it.
Run Code Online (Sandbox Code Playgroud)

函数()使范围 - 而不是'括号' {}.最简单的解决方法通常是使用函数来解决问题,因为它们会创建词法范围.例如,npm上最受信任的库,lodash就是基于此.我想你会写一天比一天JS越来越少循环为你的进步,并使用更多的功能.

关于js小提琴的工作示例:https: //jsfiddle.net/3z0hh12y/1/

你可以阅读更多有关范围和封锁这里 https://github.com/getify/You-Dont-Know-JS/blob/master/scope%20%26%20closures/ch1.md

还有一件事:当你认为你想要一个js循环时,你通常会想要Array.map(),特别是如果你正在重新映射值.