So, I'm looking at the ES5 specification at the definition of what new Object
and Object
do. To my surprise:
new Object
describes a whole algorithm of how the object constructor works - treating what happens with different kinds of values. Basically calls ToObject
on non objects - identity on objects and builds on null and undefined.Object
has a special first step for null and undefined where it builds an object and then calls ToObject
on primitives and identity on objects.After reading the description a few times - they seem identical. However, clearly from the spec they do something different. For example in Array
- calling new Array
is specified as the function call Array(…)
is equivalent to the object creation expression new Array(…)
with the same arguments.`
So - what is the difference between new Object
and Object
? Why were they specified differently?
For ease - here's a link to the spec.
The new keyword is used in javascript to create a object from a constructor function. The new keyword has to be placed before the constructor function call and will do the following things: Creates a new object. Sets the prototype of this object to the constructor function's prototype property.
Javascript is case sensitive "object" is essentially a variable that can hold anything. "Object" is an actual javascript type.
The object used in Object. create() actually forms the prototype of the new object, whereas in the new Function() from the declared properties/functions do not form the prototype. You cannot create closures with the Object.
A native object is an object or class of objects defined by the ECMAScript specification. Arrays, functions, dates, and regular expressions (for example) are native objects.
Object(window)
will never clone window
but new Object(window)
might. All current -- potentially all known -- implementations just return the same reference, although the spec allows for implementation-defined behavior.
The steps for 15.2.1.1 say:
- If value is null, undefined or not supplied, create and return a new Object object exactly as if the standard built-in Object constructor had been called with the same arguments
- Return ToObject(value).
The definition of ToObject
(9.9) lists a few types that will be caught by step 1 (in table 14), but for Object
has a very simple definition:
The result is the input argument (no conversion).
It explicitly states that the input argument will be returned as-is, so they should be equal references (===
).
The definition for new Object
(15.2.2.1) has a similar chain of type-checks in step 1, but the step for objects (1.a) is:
i. If the value is a native ECMAScript object, do not create a new object but simply return value.
ii. If the value is a host object, then actions are taken and a result is returned in an implementation-dependent manner that may depend on the host object.
That is, for any host object foo
, the call Object(foo)
must === foo
but new Object(foo)
may === foo
.
Host objects are defined in 4.3.8 to be
object supplied by the host environment to complete the execution environment of ECMAScript.
This answer lists a few host objects to include window
, history
, etc. Running those through new Object(foo)
should (but doesn't have to) return a different object.
In any case but passing a host object, new Object(foo)
seems to be a more complicated chain that defers to ToObject
in much the same way as Object(foo)
.
Unfortunately, 15.2.2.1.1.a.ii states that the "result is returned in an implementation-dependent manner" and has no specifics as to the "actions [that] are taken" and it appears that Chrome will return the same object (equal references) for all of the listed "host objects."
Using this script to check:
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);
}
}
doesn't find any objects where Object
and new Object
behave differently. @Xotic750 seems to be right that it can be implementation-dependent, but nobody is using it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With