2012-03-16 8 views
5

ES5 agregó un number de methods a Object, que parecen romper la consistencia semántica de JavaScript.¿Por qué los métodos de objeto ES5 no se agregaron a Object.prototype?

Por ejemplo, antes de esta extensión, la API de JavaScript siempre giraba en torno al operarting en el objeto en sí;

var arrayLength = [].length; 
var firstPosInString = "foo".indexOf("o"); 

... donde como son los nuevos métodos de Objeto;

var obj = { }; 
Object.defineProperty(obj, { 
    value: 'a', 
    writable: false 
}); 

... cuando el siguiente habría sido mucho más conformante:

var obj = { }; 
obj.defineProperty({ 
    value: 'a', 
    writable: false 
}); 

Puede alguien me refresque la curiosidad de por qué es esto? ¿Hay algún fragmento de código que rompa? ¿Hay algún debate público realizado por el comité de normas sobre por qué eligieron este enfoque?

Respuesta

5

Todo esto se explica muy bien en "Proposed ECMAScript 3.1 Static Object Functions: Use Cases and Rationale" document (pdf) por el propio Allen Wirfs-Brock (editor de la especificación ES5 y miembro de TC39).

Le sugiero leerlo todo. Es bastante corto, de fácil digestión y da una buena idea del proceso de pensamiento detrás de estas adiciones de ES5.

Pero para citar sección correspondiente (el énfasis es mío):

se consideraron una serie de alternativas de diseños API antes de elegir el API propuesto. En el curso de considerar alternativas, desarrollamos un conjunto de pautas informales que aplicamos cuando considerando las alternativas. Estas directrices son:

  • limpiamente separar las capas meta y aplicación.
  • Intente minimizar el área de superficie de API (es decir, el número de métodos y la complejidad de sus argumentos).
  • Enfoque en la usabilidad en el nombramiento y diseño de parámetros.
  • Intente aplicar elementos básicos de un diseño repetidamente.
  • Si es posible, habilite programadores o implementaciones para optimizar de manera estática los usos de la API.

[...]

Estas son algunas de las alternativas que se consideraron que conducen a el diseño seleccionado.

La idea inicial obvia, siguiendo el ejemplo del método estándar ya existente Object.prototype.propertyIsEnumerable, era añadir “...” propertyIs adicionales sobre métodos de consulta para Object.prototype los otros atributos y un paralelo conjunto de métodos de cambio de atributos.

[...]

Como hemos considerado este enfoque había un número de cosas sobre él que no nos gusta y que parecían contrarias al diseño API por encima de directrices:

  • Es combina en lugar de separa las capas de meta y aplicación. Como métodos en Object.prototype, los métodos serían parte de la interfaz pública de cada objeto de aplicación en un programa. Como tales, necesitan para que los entiendan todos los desarrolladores, no solo los diseñadores de bibliotecas.

[...]

+0

Interesante ... ¿sabes cómo se alinea con' Object.create'? ¿Crockford lo propuso como 'Object.create' después de que se hubieran tomado estas decisiones, o antes de eso? –

+0

Buena pregunta. No tengo ni idea :) Creo que Crockford renombró su 'Object.beget' a' Object.create' aproximadamente al mismo tiempo cuando se discutieron estas API. FWIW, el documento dice: "Observe que Object.create sin su segundo argumento opcional es esencialmente la misma operación que la función engendrada que se promovió ampliamente. Nosotros (quizás no sorprendentemente) estamos de acuerdo con la utilidad de esta función, pero sentimos que la palabra "engendrar" probablemente sea confusa para muchos hablantes no nativos de inglés .'_ – kangax

+3

Crockford participó directamente en el diseño ES5 y propuso originalmente "engendrar". "crear" surgió como el nombre preferido durante las discusiones de diseño posteriores. Cambió el nombre de "engendrar" en su libro para reflejar la decisión de diseño de ES. –

1

la API de JavaScript siempre giró en torno al funcionamiento en el objeto mismo;

Esto no es correcto. P.ej. JSON y Math siempre tenían métodos propios. Nadie hace este tipo de cosas:

var x = 0; 
x.cos(); // 1.0 
({"a":[0,1],"p":{"x":3,"y":4}}).toJSON(); 

Hay numerosos artículos en la web acerca de por qué se extiende Object.prototype es una mala cosa. Sí, están sobre cliente código, pero quizás esto es malo para los métodos de construcción también para algunos puntos.

+1

tomo su punto sobre 'Math' ... pero las diferencias entre extendiéndose' Object.prototype' como cliente * * y como el propio lenguaje son completamente diferentes ; las extensiones del * idioma * no aparecen en 'for (in)', donde las extensiones * client * sí lo hacen: http://jsfiddle.net/mDfCe/1/ – Isaac

+0

Ah, sí. Me equivoco. – kirilloid

+0

... que se debe a que esas propiedades ('.constructor',' .hasOwnProperty' etc.) se definen de forma nativa con el atributo "enumerable" establecido en falso. A partir de ES5 también podemos crear nuestras propias propiedades que no aparecen en bucles 'for in' (con el segundo argumento' Object.defineProperty' y 'Object.create') – Krinkle

Cuestiones relacionadas