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 aToObject
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 aToObject
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:
- 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
- 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.