'nuevo objeto' vs 'Objeto' en la especificación ECMAScript


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

  • new Object describe un algoritmo completo de cómo funciona el constructor de objetos - tratando lo que sucede con diferentes tipos de valores. Básicamente llama a ToObject en objetos no - identidad en objetos y construye sobre null e undefined.
  • Object tiene un primer paso especial para null e undefined donde construye un objeto y luego llama a ToObject en primitivas e identidad en objeto.

Después de leer la descripción unas cuantas veces, parecen idénticos. Sin embargo, claramente de la especificación hacen algo diferente. Por ejemplo, en Array - calling new Array se especifica como la función call Array(…) es equivalente a la expresión de creación de objetos new Array(…) con los mismos argumentos.`

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

Para la facilidad-aquí está un enlace a la especificación.

Author: Benjamin Gruenbaum, 2015-06-12

1 answers

Object(window) nunca clonará window pero new Object(window) podría. Todas las implementaciones actuales potentially potencialmente todas las 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, indefinido o no suministrado, cree y devuelva un nuevo objeto objeto exactamente como si el constructor de objetos incorporado estándar hubiera sido llamado con los mismos argumentos
  2. Devuelve toObject(valor).

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

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

Establece explícitamente que el argumento de entrada se devolverá tal cual, por lo que deben ser referencias iguales (===).

La definición de new Object (15.2.2.1) tiene una cadena similar de comprobaciones de tipo en el paso 1, pero el paso para objetos (1.un) is:

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

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

Que es, para cualquier objeto host foo, la llamada Object(foo) debe === foo pero new Object(foo) puede === foo.

Los objetos host se definen en 4.3.8 como

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

Esta respuesta enumera algunos objetos host a incluir window, history, etc. Corriendo a través de ellos new Object(foo) debe (pero no tiene que) devolver un objeto diferente.

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

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

Usando este script para comprobar:

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 se comporten de manera diferente. @Xotic750 parece tener razón de que puede ser depende de la implementación, pero nadie lo está usando.

 16
Author: ssube,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:08:57