Ответ 1
Object(window)
никогда не будет клонировать window
, но new Object(window)
может. Все текущие - потенциально все известные - реализации просто возвращают одну и ту же ссылку, хотя спецификация допускает поведение, определяемое реализацией.
Шаги для 15.2.1.1 говорят:
- Если значение равно null, undefined или не указано, создайте и верните новый объект Object точно так же, как если бы стандартный встроенный конструктор Object был вызван с теми же аргументами
- Return ToObject (значение).
В определении ToObject
(9.9) перечислены несколько типов, которые будут пойманы на шаге 1 (в таблице 14), но для Object
имеет очень простое определение:
Результат - входной аргумент (без преобразования).
В нем явно указано, что входной аргумент будет возвращен как-is, поэтому они должны быть равными ссылками (===
).
Определение для new Object
(15.2.2.1) имеет аналогичную цепочку проверок типов на шаге 1, но шаг для объектов (1.a):
я. Если значение является родным объектом ECMAScript, не создавайте новый объект, а просто возвращайте значение.
II. Если значение является объектом-хозяином, тогда предпринимаются действия и результат возвращается зависимым от реализации образом, который может зависеть от объекта-хоста.
То есть для любого объекта-хоста foo
вызов Object(foo)
должен === foo
, но new Object(foo)
может === foo
.
Объекты хоста определены в 4.3.8 как
предоставленный средой хоста для завершения среды выполнения ECMAScript.
В этом ответе перечислены несколько объектов-хостов для включения window
, history
и т.д. Запуск этих объектов через new Object(foo)
должен (но не должен ) возвращает другой объект.
В любом случае, но передавая объект-хост, new Object(foo)
представляется более сложной цепочкой, которая отбрасывает ToObject
во многом так же, как Object(foo)
.
К сожалению, в 15.2.2.1.1.a.ii указано, что "результат возвращен зависимым от реализации образом" и не имеет каких-либо особенностей относительно "действий [которые] приняты", и кажется, что Chrome вернется один и тот же объект (равные ссылки) для всех перечисленных "объектов хоста".
Используя этот script, чтобы проверить:
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);
}
}