For this question, I'm not expecting a solution to solve something but would like to understand things better ..
Some quote from the specifications:
Edition 5.1 (Link)
§15.2.3.5 Object.create ( O [, Properties] )
The create function creates a new object with a specified prototype. When the create function is called, the following steps are taken:
- If Type(O) is not Object or Null throw a TypeError exception.
- Let obj be the result of creating a new object as if by the expression new Object() where Object is the standard built-in constructor with that name
- Set the [[Prototype]] internal property of obj to O.
- If the argument Properties is present and not undefined, add own properties to obj as if by calling the standard built-in function Object.defineProperties with arguments obj and Properties.
- Return obj.
Edition 6 - draft (Link)
§19.1.3.2 Object.create ( O [, Properties] )
The create function creates a new object with a specified prototype. When the create function is called, the following steps are taken:
- If Type(O) is not Object or Null throw a TypeError exception.
- Let obj be the result of the abstract operation ObjectCreate with argument O.
- If the argument Properties is present and not undefined, then a. Return the result of the abstract operation ObjectDefineProperties(obj, Properties).
- Return obj.
If I understood correctly, both of the specs allow the following code to be executed:
function F() {
}
var x=Object.create(F);
// a minimal test
alert(x.prototype.constructor===F); // true
alert(x instanceof Function) // true
alert(typeof x) // 'object'
Seems it created an object of a type derives from (sorry for the poor terminology .. )Function
as I tested in FireFox, and so x
is non-invocable:
x(); // x is not a function
I'm thinking about why doesn't it either disallow a constructor to be used as O
or just create a valid constructor.
So I'm wondering what would you expect Object.create to do with a constructor?
Unfortunately that won't work. What you have is an object that has F
in its prototype chain; the fact that F
is a function doesn't make x
a function.
Only objects created via a function declaration or a function expression will have "Function" as their [[Class]], and a [[Call]] method, which makes it callable. Those are created according to the steps detailed on section 13.2 of the ECMAScript 5 specification.
The algorithm for Object.create
does something different, as you can see on your quote. In your case, x
will be a regular object with [[Class]] "Object" and no [[Call]] method. If you try Object.prototype.toString.call(x)
, you'll get "[object Object]"
, where "Object" is the [[Class]] of x
. x instanceof Function
only returns true
because the Function
constructor is part of the prototype chain of x
(via F
).
I'm not sure if any of that is going to be changed in ES6, but I suppose it won't.
So I'm wondering what would you expect Object.create to do with a constructor?
I would expect it to follow the spec of course…
I'm thinking about why doesn't it either disallow a constructor to be used as O
Why should it? Every constructor function is an object (§8.6).
… or just create a valid constructor.
The spec says it should create a plain object (as by new Object
), whose [[prototype]] is set to O. Plain objects are no functions, they don't have a [[call]] or [[construct]] property. It also will have [[class]] Object
, not Function
.
x.prototype.constructor===F // true x instanceof Function // true typeof x // 'object'
Seems it created an object of a type derives from (sorry for the poor terminology .. ) Function
From F
, actually. It does inherit the .prototype
property from F
(that's why your first test is true
), and through F
it also inherits from Function.prototype
which makes it instanceof Function
. Yet, it doesn't have a [[call]] property (it's not callable) so typeof
does not yield "function"
, but just "object"
.
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