values name method keys es6 entries array and javascript language-lawyer ecmascript-5

javascript - name - `new Object` vs` Object` en la especificación ECMAScript



object.entries javascript (1)

Por lo tanto, estoy mirando la especificación ES5 en la definición de lo que hacen el new Object y el Object . Para mi sorpresa:

  • new Object describe todo un algoritmo de cómo funciona el constructor de objetos, tratando lo que sucede con diferentes tipos de valores. Básicamente, llama a ToObject en objetos distintos: identidad en objetos y se basa en nulos e indefinidos.
  • Object tiene un primer paso especial para null e indefinido donde construye un objeto y luego llama a ToObject en primitivos e identidad en objetos.

Después de leer la descripción varias veces, parecen idénticas. Sin embargo, claramente de la especificación hacen algo diferente. Por ejemplo, en Array : la llamada a new Array se especifica como la función llamada Array(…) es equivalente a la expresión de creación de objeto new Array(…) con los mismos argumentos ».

Entonces, ¿cuál es la diferencia entre new Object y Object ? ¿Por qué se especificaron de manera diferente?

Para mayor facilidad, aquí hay un enlace a la especificación .


Object(window) nunca clonará la window pero el new Object(window) podría. Todas las implementaciones actuales, potencialmente todas conocidas, solo devuelven la misma referencia, aunque la especificación permite un comportamiento definido por la implementación.

Los pasos para 15.2.1.1 dicen:

  1. Si el valor es nulo, no está definido o no se ha proporcionado, cree y devuelva un nuevo Objeto exactamente como si se hubiera llamado al constructor de Objeto incorporado estándar con los mismos argumentos
  2. Devuelve ToObject (valor).

La definición de ToObject (9.9) enumera algunos tipos que se capturarán en el paso 1 (en la tabla 14), pero para Object tiene una definición muy simple:

El resultado es el argumento de entrada (sin conversión).

Indica explícitamente que el argumento de entrada se devolverá como está, por lo que deben ser referencias iguales ( === ).

La definición de new Object (15.2.2.1) tiene una cadena similar de verificaciones de tipos en el paso 1, pero el paso para los objetos (1.a) es:

yo. Si el valor es un objeto ECMAScript nativo, no cree un nuevo objeto sino que simplemente devuelva el valor.

ii. Si el valor es un objeto de host, se toman acciones y se devuelve un resultado de una manera dependiente de la implementación que puede depender del objeto de host.

Es decir, para cualquier objeto host foo , el Object(foo) llamada Object(foo) debe === foo pero el new Object(foo) puede === foo .

Los objetos host se definen en 4.3.8 para ser

Objeto suministrado por el entorno host para completar el entorno de ejecución de ECMAScript.

Esta respuesta enumera algunos objetos del host para incluir window , history , etc. Ejecutar esos a través del new Object(foo) debería (pero no tiene que) devolver un objeto diferente.

En cualquier caso, pero al pasar un objeto host, el new Object(foo) parece ser una cadena más complicada que difiere a ToObject de la misma manera que el Object(foo) .

Desafortunadamente, 15.2.2.1.1.a.ii declara que el "resultado se devuelve de una manera dependiente de la implementación" y no tiene detalles sobre las "acciones [que] se toman" y parece que Chrome devolverá el mismo objeto (referencias iguales) para todos los "objetos de host" enumerados.

Usando este script para verificar:

var objects = [ /* Native objects */ ''Object'', ''Date'', ''Math'', ''parseInt'', ''eval'', /* Host objects */ ''window'', ''document'', ''location'', ''history'', ''XMLHttpRequest'', ''setTimeout'' ]; function getDefinedReference(name) { if (eval(''typeof '' + name) !== ''undefined'') { return eval(name); } else { throw new Error('''' + name + '' is not defined.''); } } function checkIdentity(name) { try { var ref = getDefinedReference(name); var no = new Object(ref); var o = Object(ref); console.log(name, ref === no, ref === o, no === o); if (ref === o && no !== o) { // Make sure ref === Object(ref) but not new Object(ref) console.log(name, ''returns different references.''); } } catch (e) { console.warn(e); } } objects.forEach(checkIdentity); if (typeof window !== ''undefined'') { for (var f in window) { checkIdentity(f); } }

no encuentra ningún objeto donde Object y new Object comportan de manera diferente. @ Xotic750 parece estar en lo cierto en que puede ser dependiente de la implementación, pero nadie lo está utilizando.