Разница между Array.slice и Array (). Slice

Я просматриваю превосходный Расширенный учебник по javascript Джона Ресига, и я не совсем понимаю, в чем разница между следующими вызовами: (обратите внимание, что 'arguments' - это встроенное слово javascript и не совсем массив, поэтому взлом с Array.slice вместо просто вызывая arguments.slice)

>>> arguments  
[3, 1, 2, 3]  
>>> Array.slice.call( arguments )  
3,1,2,3 0=3 1=1 2=2 3=3  
>>> Array.slice.call( arguments, 1 )  
[]
>>> Array().slice.call( arguments )  
3,1,2,3 0=3 1=1 2=2 3=3  
>>> Array().slice.call( arguments, 1 )  
1,2,3 0=1 1=2 2=3  

В основном мое недоразумение сводится к разнице между Array.slice и Array (). Slice. В чем именно разница между этими двумя и почему Array.slice.call не работает должным образом? (который возвращает все, кроме первого элемента списка аргументов).

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
27
0
15 171
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

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

Array().slice.call

такой же как

[].slice.call

Что ж,

Глядя на http://www.devguru.com/Technologies/ecmascript/quickref/slice.html

Array (). Slice - это функция (конструктор) в классе массива, ее нельзя использовать в качестве элемента данных. Если вы не хотите использовать '()', вам нужно будет вызвать его в массиве. т.е. - arguments.slice (1)

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

Я считаю, что Множество - это тип, а Множество() - это функция-конструктор.

Возился в FireBug:

>>> Array === Array()
false

>>> Array.constructor
Function()

>>> Array().constructor
Array()
Ответ принят как подходящий

Не совсем.

Посмотрите, что происходит, когда вы вызываете String.substring.call ("foo", 1) и String (). Substring.call ("foo", 2):

>>> String.substring.call("foo", 1)
"1"

>>> String().substring.call("foo", 1)
"oo"

Array.slice - это ни один, правильно ссылаясь на функцию среза, прикрепленную к прототипу массива, ни на функцию среза, прикрепленную к какому-либо созданному экземпляру массива (например, Array () или []).

Тот факт, что Array.slice вообще не равен нулю, является неправильной реализацией самого объекта (/ функции / конструктора). Попробуйте запустить эквивалентный код в IE, и вы получите ошибку, что Array.slice имеет значение null..

Вот почему Array.slice работает некорректно (как и String.substring).

Доказательство (этого нельзя ожидать, основываясь на определении slice () ... точно так же, как substring () выше):

>>> Array.slice.call([1,2], [3,4])
3,4

Теперь, если вы правильно вызовете slice () для любого экземпляра объекта или же, прототипа массива, вы получите то, что ожидаете:

>>> Array.prototype.slice.call([4,5], 1)
[5]
>>> Array().slice.call([4,5], 1)
[5]

Больше доказательств ...

>>> Array.prototype.slice == Array().slice
true
>>> Array.slice == Array().slice
false

Я не знаю, как он вел себя в браузерах '08, но по состоянию на начало 2013 года String.substring.call выдает ошибку TypeError в Chrome (поскольку конструктор String не имеет свойства substring).

bfavaretto 21.01.2013 22:42

@bfavaretto, Firefox (один) реализует Array.slice и String.substring. Спрашивающий, несомненно, использовал Firefox, когда пробовал это.

Nathan Wall 30.01.2013 22:28

Спасибо за информацию, @NathanWall. Это довольно странно для Firefox, вероятно, они добавили его как ярлык для String.prototype.substring и др. для обратной совместимости ... и, по-видимому, какое-то время он держится.

bfavaretto 30.01.2013 22:51

Как любой вызов slice.call () работает в приведенных примерах, если параметр контекста не предоставляется? Реализует ли slice собственный метод вызова, тем самым переопределяя метод вызова JavaScript? Методы call и apply принимают в качестве первого параметра объект, определяющий объект контекста (this), применяемый к вызову.

Другие вопросы по теме