Подтвердить что ты не робот

Array.prototype.fill() с объектом передает ссылку, а не новый экземпляр

Небольшой вопрос.

Я немного искал и пытался создать новый массив длины 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? Или я должен просто преобразовать его в цикл?

Спасибо заранее!

4b9b3361

Ответ 1

Вы можете сначала fill массива с любым значением (например, undefined), а затем вы сможете использовать map:

var arr = new Array(2).fill().map(u => ({}));
var arr = new Array(2).fill().map(Object);

Ответ 2

Принятый ответ хорош и будет работать в 90% случаев.

Но если вы создаете приложение JS с высокой производительностью, и если вы работаете с большими/огромными массивами, Array.map(..) создает большую перегрузку в обоих случаях - памяти и процессора, поскольку он создает копию массива.

Я рекомендую использовать классический цикл для:

    a = new Array(ARRAY_SIZE);
    for (var i = 0; i < ARRAY_SIZE; i++) {
        a[i] = [];
    }

Я протестировал три альтернативы и получил следующее:

  • Предлагаемый ответ ( 11x раз!!! медленнее):

    a = new Array(ARRAY_SIZE).fill().map(u => { return []; });
    
  • Простой цикл (самый быстрый):

    a = new Array(ARRAY_SIZE);
    for (var i = 0; i < ARRAY_SIZE; i++) {
        a[i] = [];
    }
    
  • forEach ( 2x время медленнее):

    a = new Array(ARRAY_SIZE).fill();
    a.forEach((val, i) => {
        a[i] = [];
    })
    

PS. Я использовал эту скрипту для тестов.