Разница между Array.slice и Array (). Slice - PullRequest
27 голосов
/ 23 сентября 2008

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

Ответы [ 6 ]

39 голосов
/ 23 сентября 2008

Не совсем.

Посмотрите, что происходит, когда вы вызываете 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
6 голосов
/ 23 сентября 2008

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

Array().slice.call

совпадает с

[].slice.call
1 голос
/ 28 ноября 2009

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

0 голосов
/ 23 сентября 2008

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

Возиться в FireBug :

>>> Array === Array()
false

>>> Array.constructor
Function()

>>> Array().constructor
Array()
0 голосов
/ 23 сентября 2008

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

0 голосов
/ 23 сентября 2008

Ну

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...