Вопрос

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

Это было полезно?

Решение

Не совсем.

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

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

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

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

Теперь, если вы правильно вызоветеlice() для созданного объекта или прототипа 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

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

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

Array().slice.call

такой же как

[].slice.call

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

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

Возиться в FireBug:

>>> Array === Array()
false

>>> Array.constructor
Function()

>>> Array().constructor
Array()

Хорошо,

Смотря на http://www.devguru.com/Technologies/ecmascript/quickref/slice.html

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top