Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
356 views
in Technique[技术] by (71.8m points)

javascript - x is not a function ... what would you expect Object.create to do with a constructor

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:

    1. If Type(O) is not Object or Null throw a TypeError exception.
    2. 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
    3. Set the [[Prototype]] internal property of obj to O.
    4. 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.
    5. 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:

    1. If Type(O) is not Object or Null throw a TypeError exception.
      1. Let obj be the result of the abstract operation ObjectCreate with argument O.
      2. If the argument Properties is present and not undefined, then a. Return the result of the abstract operation ObjectDefineProperties(obj, Properties).
      3. 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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...