[] .slice или Array.prototype.slice - PullRequest
17 голосов
/ 25 января 2012

Я сталкивался с обоими способами применения прототипов Array к собственному объекту:

arr = Array.prototype.slice.call(obj);
arr = [].slice.call(obj);

Аналогичным образом получается истинный тип нативного массива-подобного объекта:

type = Object.prototype.toString.call(obj);
type = {}.toString.call(obj);

Простой тест:

function fn() {
    console.log(
        Array.prototype.slice.call(arguments),
        [].slice.call(arguments),
        Object.prototype.toString.call(arguments), 
        {}.toString.call(arguments)
    );
}

fn(0,1);

Скрипка: http://jsfiddle.net/PhdmN/

Они кажутся мне идентичными; первый синтаксис используется чаще, но второй определенно короче. Есть ли недостатки при использовании более короткого синтаксиса?

Ответы [ 2 ]

25 голосов
/ 25 января 2012

Они идентичны по функциональности.

Однако объект Array может быть перезаписан, что приведет к сбою первого метода.

//Example:
Array = {};
console.log(typeof Array.prototype.slice); // "undefined"
console.log(typeof [].slice);    // "function"

Литеральный метод создает новый экземпляр Array (в отличие от Array.prototype. метода). Ориентир обоих методов: http://jsperf.com/bbarr-new-array-vs-literal/3

Если вы собираетесь использовать метод много раз, рекомендуется кешировать метод:

  • var slice = Array.prototype.slice; //Commonly used
  • var slice = [].slice; - Если вас беспокоит существование Array или вам просто нравится более короткий синтаксис.
0 голосов
/ 15 октября 2018

Это интересный вопрос!Давайте подберём плюсы (✔️) и минусы (❌) для каждой альтернативы:

  1. [].slice
    • ✔️: набирается быстрее
      Два нажатия клавиш, нет shift -модификатор или что-нибудь,
      ваш линтер знает [.slice опечатка.
    • ✔️: читается быстрее
      Вы можете идентифицировать соответствующую часть (slice)быстрее.
    • ✔️: более популярны
      56M + фрагменты на GitHub (по состоянию на конец 2018 года).
    • ✔️: невозможно перезаписать
      Первая часть Ответ Роба наглядно демонстрирует это.
    • ✔️: работает быстрее.
      Подождите, что?Ну, в этом-то и весь смысл этого ответа.

Вопреки тому, что вы думаете и читаете почти везде, [].slice.call(...) делает НЕ создать новую пустую Array просто для доступа к свойству slice! .

В наше время (так было в течение 5+ лет - в последнее время2018), JIT-компиляция (1) включена везде, где вы запускаете JavaScript (если вы все еще не просматриваете Интернет с IE8 или ниже).

Этот механизм позволяет JS Engine:(2)

... разрешить [].slice напрямую и статически как прямую ссылку Array.prototype в одном кадре и только один доступ к настраиваемому свойству: forEach

Array.prototype.slice

  • ❌: набирается медленнее
    Опечатки (например: Array.prorotype.slice) выглядят хорошо, пока вы не попытаетесь запустить код.
  • ❌: Менее популярен
    8M + фрагменты на GitHub (по состоянию на конец 2018 года).
  • ❌: работает медленнее
    Array.prototype.slice: (2)

    ... поиск всей области для ссылки Array до тех пор, пока все области не пройдены до global one ... потому что выможет присвоить имя переменной Array в любое время.

    Как только глобальная область действия достигнута и найден собственный, механизм обращается к своему прототипу, а после этого к его методу
    ...
    O(N) разрешение области + доступ к 2 свойствам (.prototype и .forEach).

  • ✔️: Позволяет легко адаптироваться к любым соглашениям по кодированию, которые строго запрещают вамот начала строки с (, [ или `
    Определенно хорошая вещь.

  • ✔️: вам не придется объяснять, почему [].sliceлучше в красивоймного всякого пути
    Хотя сейчас это просто сводилось бы к нажатию на ссылку общего доступа ниже ?

Отказ от ответственности: обратите внимание, что реально нидействительно работает быстрее , чем другие.Это не является узким местом вашего приложения.


  1. Возможно, вы захотите прочитать Ускоренный курс для JIT-компиляторов
  2. Цитируется из Андреа Джаммарки ( @ WebReflection в Twitter)
...