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

Array.of vs "[]". Когда использовать Array.of над "[]"?

Я немного читал, когда нашел Array.of.

В соответствии с MDN,

Метод Array.of() создает новый экземпляр Array с переменным числом аргументов, независимо от числа или типа аргументов.

var a = Array.of(1,2,3,4,5);
console.log(a)
4b9b3361

Ответ 1

Существует одна тонкая разница между конструктором Array.of() и Array()/[]. Обычно, как и Array(), this в Array.of() будет объектом Array, и он будет использовать Array.constructor, который function Array(), чтобы построить результат.

Однако Array.of может вести себя по-другому, изменяя связанный контекст. Если связанный контекст может использоваться как конструктор (если связанный объект является функцией), он будет использовать эту функцию для построения. Поэтому давайте привяжите Array.of() к функции и посмотрим, что произойдет.

function Test(n){console.log(n)}
Test.prototype.last = function(){return this[this.length-1]};

var what = Array.of.call(Test, [5,6,7], {a:0,b:1}, 42, null, "this is last");
console.log(JSON.stringify(what,null,2));
console.log(what.last());

Ответ 2

Хотя этот метод, возможно, был стандартизирован, он кажется неподдерживаемым в нескольких браузерах, поэтому использование его кажется рискованным и, как вы заметили, довольно бессмысленным.

Утилита этой функции, по-видимому, предназначена для случаев, когда вам нужно объявить массив, но не хотите собирать его из частей. То есть вы хотите передать несколько аргументов некоторой функции, которая затем возвращает массив.

Если вы следуете ссылкам на оправдание этого метода, вы получите следующее:

Случай использования - это когда вы не можете написать литерал, потому что вы передаете функцию -что-конструкцию как funarg, а конечный вызывающий может передать только один аргумент arg или несколько аргументов. В этом случае массив не будет делать правильную вещь в случае с одним номером-аргументом.

Это в основном способ сказать: "Эта функция может получать списки аргументов переменной длины и будет последовательно возвращать массивы, заполненные правильными значениями", но, как на практике, которая преобразует массив в... массив, я не полностью убежден, что эта вещь должна существовать, и, видимо, многие разработчики браузеров имеют сходное мышление.

Толчок для Array.of в значительной степени является ответом на то, что new Array() ведет себя непоследовательно:

new Array(2);
// [ , ] 2-element array that unpopulated

new Array(1,2);
// [1,2] 2-element array populated with the provided values

Array.of всегда будет работать как последняя версия.

Ответ 3

Итерируя ответ Redu, вы можете использовать ArraySubclass.of для создания экземпляров подкласса массива. Например, вы можете создать обертку Array-subclass вокруг lodash Методы массива.

Например:

_.Array = class extends Array {
  uniq() {
    return _.Array.from(_.uniq(this));
  }
  last() {
    return _.last(this);
  }
  flatten() {
    return _.Array.from(_.flatten(this));
  }
  // ... more methods
}

_.Array.of([1,2,3], [3,4,5]) // <_.Array> [[1,2,3],[3,4,5]]
  .flatten()                 // <_.Array> [1,2,3,3,4,5]
  .uniq()                    // <_.Array> [1,2,3,4,5]
  .last()                    // <number> 5

JSFiddle


Изменить

В результате я использовал этот пример для использования ES Proxies.

_.Array = class extends Array { }
_.Array.prototype = new Proxy(Array.prototype, {
  get(proto, name) {
    if (name in _) return function (...args) {
        const ret = _[name](this, ...args);
        return Array.isArray(ret) ? _.Array.from(ret) : ret;
    }
    return proto[name];
  }
});

Теперь доступна всякая функция lodash, и возвращаемые массивы завернуты в класс _.Array, аналогично _(array) неявной цепочке.