Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/373.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 带有对象的Array.prototype.fill()传递引用,而不是新实例_Javascript_Arrays - Fatal编程技术网

Javascript 带有对象的Array.prototype.fill()传递引用,而不是新实例

Javascript 带有对象的Array.prototype.fill()传递引用,而不是新实例,javascript,arrays,Javascript,Arrays,我在玩弄一些东西,试图实例化一个长度为x的新数组,其中该数组的所有元素都初始化为值y: var arr = new Array(x).fill(y); 如果y的值不是对象,则此操作非常有效。 这意味着如果y是一个对象,则以下为真: var arr = new Array(2).fill({}); arr[0] === arr[1]; //is true; arr[0].test = 'string'; arr[1].test === 'string'; //is also true; 在使用

我在玩弄一些东西,试图实例化一个长度为
x
的新数组,其中该数组的所有元素都初始化为值
y

var arr = new Array(x).fill(y);
如果
y
的值不是对象,则此操作非常有效。 这意味着如果
y
是一个对象,则以下为真:

var arr = new Array(2).fill({});
arr[0] === arr[1]; //is true;
arr[0].test = 'string';
arr[1].test === 'string'; //is also true;

在使用fill函数时,是否有任何方法可以声明应该为每个元素创建一个新对象?或者我应该将其转换为一个循环吗?

您可以首先
使用任何值(例如
未定义的
)填充
数组,然后您就可以使用
映射

var arr=newarray(2.fill().map(u=>({}));
var arr=新数组(2).fill().map(对象);

公认的答案是好的,在90%的情况下都有效

但是,如果您正在制作高性能的JS应用程序,并且您使用的是大型/大型阵列,Array.map(…)会在内存和处理器使用方面创建大型重载,因为它会创建阵列的副本

我建议使用经典的for循环:

    a = new Array(ARRAY_SIZE);
    for (var i = 0; i < ARRAY_SIZE; i++) {
        a[i] = [];
    }
  • 对于循环,最好的(最快的):

  • [更新2020-08-27]下面是伊利亚斯·卡里姆提出的另一种方法

    • 数组。从30倍!!!较慢)-性能明显较差,尽管语法最好:(

    • […数组(…)]5倍!!!较慢)

    • 阵列。推送(…),性能排名第二(2倍!!!较慢)

    PS.I用于测试。

    一种性能解决方案:
    Array.from({length:5},()=>newobject())

    Ilias Karim的答案非常好。我刚刚做了以下几点:

    a = Array.from({length:l}, () => new Array(c).fill(prefix));
    
    要创建指定大小的预填充2D数组,请使用前缀l x c。现在,我的代码可以填充2D矩阵中需要非前缀值的插槽。

    最短可能:

    let node=[…数组(2)].map(=>({}))
    
    console.log(node)
    您还可以通过以下解决方法来解决此问题

    var arr = new Array(2).fill({});
    arr = JSON.parse(JSON.stringify(arr));
    

    还有
    Array.from({length:2},u=>({}))
    不幸的是,这种方法的性能不是最好的。我在下面对我的答案添加了更多的解释。@Slai非常好的答案,谢谢你。我花了一段时间才弄明白,但它是值得的。可以写得更短:
    Array.from({length:5},{u=>{})
    check jsperf.microbenchmarks value Resisting,fill and map从v80开始仍优于Chrome中的array.from。很可能是因为压缩数组迭代速度快。我刚刚在上面的答案中添加了这种初始化方式,显然,就性能而言,它是最差的方式。在我的测试中,这种方式显示的结果比定期的loop@morphles它应该是
    。=>({})
    如果你想初始化对象。否则,你只需要用
    未定义的
    填充数组。这不是一个公平有效的比较,因为你预先初始化了数组并为for循环创建了一个压缩数组。你的基准测试将重复的对象初始化时间与预先初始化的本机数组迭代进行比较。请看一看预填充数组的方式,或将元素类型更改为非同构的方式,此基准就会崩溃。@user120242我不理解您的评论?此问题的含义是:如何使用值初始化数组?我只是与公认的答案进行了比较,发现了更快的方法。如果您有赌注的话对于阵列初始化的建议,请免费填写并与我们共享:)我也测试了这一个,它比旧的循环方式慢5倍。性能测试见上面我的答案。
    
     a = new Array(ARRAY_SIZE).fill();
     a.forEach((val, i) => {
         a[i] = [];
     })
    
     a = Array.from({ length: ARRAY_SIZE }, () => []);
    
     a = [...Array(ARRAY_SIZE)].map(_=>([]))
    
     let a = [], total = ARRAY_SIZE;
     while(total--) a.push([]);
    
    a = Array.from({length:l}, () => new Array(c).fill(prefix));
    
    var arr = new Array(2).fill({});
    arr = JSON.parse(JSON.stringify(arr));