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

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

Я отлично разбираюсь в John Resig Расширенное руководство по 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 ведет себя так, как ожидалось? (который возвращает все, кроме первого элемента списка аргументов).

4b9b3361

Ответ 1

Не совсем.

Смотрите, что происходит, когда вы вызываете 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 (например, Array() или []).

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

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

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

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

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

>>> 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

Ответ 2

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

Array().slice.call

совпадает с

[].slice.call

Ответ 3

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

Ответ 4

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

Беседа в FireBug:

>>> Array === Array()
false

>>> Array.constructor
Function()

>>> Array().constructor
Array()

Ответ 5

Ну,

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

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

Ответ 6

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