Pregunta

Estoy repasando el excelente libro de John Resig. Tutorial avanzado de javascript y no entiendo bien cuál es la diferencia entre las siguientes llamadas:(tenga en cuenta que 'argumentos' es una palabra incorporada de JavaScript y no es exactamente una matriz, de ahí la piratería con Array.slice en lugar de simplemente llamar a 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  

Básicamente, mi malentendido se reduce a la diferencia entre Array.slice y Array().slice.¿Cuál es exactamente la diferencia entre estos dos y por qué Array.slice.call no se comporta como se esperaba?(que devuelve todo menos el primer elemento de la lista de argumentos).

¿Fue útil?

Solución

No exactamente.

Observe lo que sucede cuando llama a String.substring.call("foo", 1) y String().substring.call("foo", 2):

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

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

Array.slice es ni hacer referencia correctamente a la función de corte adjunta al prototipo de Array ni a la función de corte adjunta a cualquier instancia de Array instanciada (como Array() o []).

El hecho de que Array.slice ni siquiera sea nulo es una implementación incorrecta del objeto (/función/constructor) en sí. Intente ejecutar el código equivalente en IE y obtendrá un error que indica que Array.slice es nulo.

Esta es la razón por la que Array.slice no se comporta correctamente (tampoco String.substring).

Prueba (lo siguiente es algo que uno nunca debería esperar según la definición de segmento()...al igual que substring() arriba):

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

Ahora, si llamas correctamente a slice() en un objeto instanciado o el prototipo de Array, obtendrás lo que esperas:

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

Más pruebas...

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

Otros consejos

Array es solo una función, aunque especial (utilizada para inicializar matrices).Array.slice es una referencia a la función slice() en el prototipo de Array.Sólo se puede invocar en un objeto de matriz y no en el Constructor (es decir,Matriz) en sí.Sin embargo, Array parece comportarse de manera especial, ya que Array() devuelve una matriz vacía.Esto no parece funcionar para funciones de Constructor no integradas (ahí tienes que usar new).Entonces

Array().slice.call

es lo mismo que

[].slice.call

¿Cómo funciona cualquier llamada a slice.call() en los ejemplos proporcionados ya que no se proporciona un parámetro de contexto?¿Slice implementa su propio método de llamada, anulando así el método de llamada de JavaScript?Los métodos call y apply toman como primer parámetro un objeto para especificar el contexto (este) objeto que se aplicará a la invocación.

Yo creo Formación es el tipo y Formación() es la función constructora.

Jugando en insecto de fuego:

>>> Array === Array()
false

>>> Array.constructor
Function()

>>> Array().constructor
Array()

Bien,

Mirando a http://www.devguru.com/Technologies/ecmascript/quickref/slice.html

Array().slice es una función (constructor) en la clase de matriz. No se puede utilizar como miembro de datos.Si no desea utilizar '()', deberá llamarlo en la matriz.es decir, argumentos.slice(1)

Supongo que Array es un prototipo, mientras que Array() es un objeto de matriz real.Dependiendo de la interpretación de JavaScript, llamar directamente al método prototipo de un tipo de objeto incorporado podría funcionar o no.No creo que la especificación diga que tiene que funcionar, solo que llamarlo a un objeto instanciado funciona.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top