2010-07-14 14 views
42

ya que parece que la gente lo primero que hacen es convertir arguments en una matriz real, yo estoy interesado en por qué los autores y ejecutores Javascript decidieron, y siguen pensando, que debe arguments no ser un verdadero Array. No me refiero a esto como un bicho raro, estoy sinceramente interesado en el pensamiento detrás de eso. Dado que la función se está llamando naturalmente cuando estás en su cuerpo, no creo que sea porque los objetos arguments están haciendo referencia pueden cambiar, como con algunos de los resultados DOM ...¿Por qué los argumentos de una función no son una matriz en Javascript?

+0

Esto no es un problema en ES6. Puede usar [parámetros de reposo] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters), que es una matriz real. –

Respuesta

42

Mi conjetura:

El concepto del objeto arguments ha estado en el idioma desde el principio, de que incluso se describe en el ECMAScript First Edition Standard (PDF).

En esa versión de ECMAScript, el Array.prototype era realmente básico, los objetos de matriz contenían ¡solo 4 métodos!: toString, join, reverse y sort.

creo que es una de las principales razones que hacen sobre arguments heredar de Object.prototype, en ese momento los métodos de matriz no se veía demasiado útil.

Pero el objeto Array.prototype se extendió en las próximas versiones de la norma, ahora en ES5, objetos Array tienen métodos como map, reduce, every, some, etc, que son realmente de gran alcance .

El año pasado, hubo una propuesta en ES5 para que arguments heredara de Array.prototype, en las etapas de borrador de la norma, pero se dejó tiempo después.

En esas corrientes de aire, arguments heredado de Array.prototype, pero para la compatibilidad hacia atrás con ES3, el objeto arguments habían definido dos propiedades propias, toString y toLocaleString, tanto apuntando a los mismos métodos en Object.prototype, pero finalmente, el Comité decidió mantener heredando de Object.prototype.

+14

conjetura? parece que estuviste presente en todas esas reuniones del comité ... lol – Anurag

+5

Y quien estaba allí no lo sabe: http://www.slideshare.net/douglascrockford/newandimproved, nice wrap up por cierto +1. Pero no le dice ** por qué ** el comité "** continúa ** para pensar que' arguments' no debe ser un 'Array' real" – galambalazs

+2

@galambalazs: IMO es la razón por la cual el comité decidió que es sobre el * miedo a romper la web *, el estándar ES5 fue diseñado con mucho cuidado, evitando cualquier cambio radical, de hecho, no se introdujo ninguna nueva sintaxis en el lenguaje. La propuesta de la que hablo, IIRC, se abandonó porque discutían sobre * casos de incompatibilidad extremo *, como la redefinición del 'Object.prototype'. Ya veremos, tal vez en el futuro ... – CMS

5

Es importante tener en cuenta que sin uno de los diseñadores presentes, solo podemos conjeturar realmente por qué. Pero podemos llegar a algunas razones decentes ... aquí está el mío:

Desde la perspectiva de una función, una de las razones podría ser porque, obviamente, no se puede cambiar los argumentos que le pasaron. Puede cambiar una matriz que represente los argumentos pasados ​​a usted, pero los argumentos tal como se aprobaron están escritos en piedra antes de recibir el alcance de la ejecución.

Usted puede empalmar, dados y matrices pop, y si se hizo al objeto arguments continuación, que acaba arruinado lo que es conceptualmente una estructura inmutable (cara triste!). El diseño del objeto de argumentos reales está más cerca de un tipo de inmutabilidad que JavaScript puede ofrecer.

Es similar a los parámetros querystring. Obtiene una colección entregada por el cliente que envía la solicitud. Es parte de la información de solicitud, que ya está configurada y lista.

+4

No estoy seguro si estoy completamente de acuerdo con el razonamiento aquí. 'arguments' es solo un objeto, y aunque técnicamente no podemos cambiar los argumentos reales, podemos hacer lo que queramos con el argumento' arguments' completo o los argumentos individuales que representa a través de índices de matriz - 'arguments [0]', ' argumentos [1] ', ... ¿Por qué no se hizo un' Array' entonces, o si se le da una interfaz similar a una matriz, todavía vale la pena considerarlo, diría yo. El mismo problema se aplica a NodeList. – Anurag

+0

Rex y Anurag, ambos buenos puntos. – pr1001

+0

@Anurag No estoy necesariamente en desacuerdo ... como dije, solo podemos conjeturar por qué, y esta es mi teoría :) –

2

argumentos no solo devuelve los argumentos. Devuelve el objeto llamado y la matriz de argumentos. Si fuera solo una matriz, el primer elemento podría ser el objeto llamado y ser más confuso.

+0

Quizás la pregunta entonces debería ser, ¿por qué no hay un objeto 'callee' por separado? ¿Por qué debería ser una propiedad de 'arguments'? – pr1001

26

El objeto arguments tiene la característica muy inusual de que sus elementos similares a una matriz son sinónimos de las variables locales que contienen los argumentos de la función. Por ejemplo:

function f(x) { 
    console.log(arguments[0]); // Displays the initial value of the argument x 
    x = 5;      // Changes the value of the local variable x 
    console.log(arguments[0]); // Now displays 5 
} 

siempre tuve la impresión de que este "comportamiento mágica" es la razón por la arguments no es una matriz.

+0

Es cierto, pero también puedo tener 'function a() {console.log (arguments)}; a (1, 2, 3); '... – pr1001

+0

Sí, este comportamiento solo se aplica cuando tiene argumentos con nombre. –

+2

+1 - Eso es bastante mágico ... – gnarf

Cuestiones relacionadas