Reputation: 1021
In JavaScript, I can write:
x = new Object({ a: 3 })
and I will have x = { a: 3 }
Similarly, I can write
x = Object({ a: 3 })
and I will have x = { a: 3 }
again.
My question is: How is Object
implemented to satisfy both these ways of calling it? In the first scenario, it will receive a fresh this
, while in the second it will receive the global object.
My best guess is something like:
var Object = function(obj) {
var global = (function() { return this; })();
if (global == this) { // I am called as a regular function
// Create a copy of obj, potentially like this
return { ...obj };
} else { // I am called via new
// Copy all fields of obj onto this
// not sure what the best way to do this is.
}
}
Upvotes: 4
Views: 74
Reputation: 452
It's simple as that
function Object(obj) {
return obj;
}
When you call it as function it inherits its parent's scope that is window
.
Buy when you initialize it as a class, the function itself is the constructor that has its own scope this
.
And it's not creating a new instance with copied properties as you can see in this example:
var a = {a : 3};
var b = new Object(a);
var c = Object(a);
console.log(a === b);
console.log(a === c);
As @user2357112 specified that it's not that simple here is a more close to Object functionality:
function Object(value) {
if (typeof value === 'number') {
return new Number(value);
}
if (typeof value === 'string') {
return new String(value);
}
if (value === null || value === undefined) {
return {};
}
return value
}
var a = new Object(undefined);
console.log(new Object(1));
console.log(new Object('sad'));
console.log(new Object([]));
console.log(new Object({}));
console.log(new Object(null));
console.log(new Object());
Upvotes: -1
Reputation: 1074989
The answer is in the specificaton:
When Object function is called with optional argument value, the following steps are taken:
- If NewTarget is neither undefined nor the active function, then
- Return ? OrdinaryCreateFromConstructor(NewTarget, "%ObjectPrototype%").
- If value is null, undefined or not supplied, return ObjectCreate(%ObjectPrototype%).
- Return ! ToObject(value).
Step #1 is about what the code should do when the call is happening as part of creating something that inherits from Object
, so we can ignore that step for your question.
Step #2 doesn't apply because you're passing in value
and it's neither null
nor undefined
.
So Step #3 is what happens: It uses the ToObject
operation to do type conversion to turn value
into an object. Since value
is already an object, that's a no-op, and the result is the same object you passed in. The new Object
part of new Object({a: 1})
is completely unnecessary.
In the first scenario, it will receive a fresh
this
, while in the second it will receive the global object.
As you can see from the spec steps above, Object
doesn't use this
at all.
Upvotes: 4
Reputation: 2146
I think it is something like
function Object(obj) {
If (this instanceof Object) {
return Object.assign(this, ...obj)
}
return new Object(obj);
}
Upvotes: -1