- From: Garrett Smith <dhtmlkitchen@gmail.com>
- Date: Thu, 7 Oct 2010 23:49:27 -0700
- To: Maciej Stachowiak <mjs@apple.com>
- Cc: Cameron McCormack <cam@mcc.id.au>, "Mark S. Miller" <erights@google.com>, James Graham <jgraham@opera.com>, Travis Leithead <travil@microsoft.com>, Simon Pieters <simonp@opera.com>, "public-script-coord@w3.org" <public-script-coord@w3.org>, annevk@opera.com
On 10/7/10, Maciej Stachowiak <mjs@apple.com> wrote: > > On Oct 7, 2010, at 10:49 PM, Cameron McCormack wrote: > >> Garrett Smith: >>> My statement in the previous paragraph is regarding the algorithm for >>> [[Construct]], as specified in ECMA-262. Were you discussing a >>> different [[Construct]]? >> >> Ah, I (mis-)interpreted it as a comment on all objects’ [[Construct]], >> be they native or host objects. >> >>> In ECMA-262, step 6 of [[Construct]] is: >>> | 6. Invoke the [[Call]] property of F, providing Result(1) >>> | as the this value and providing the argument list passed >>> | into [[Construct]] as the argument values. >>> >>> Understand that an object that implements [[Construct]] implements >>> [[Call]]. What is not known is what either of those commands will do. >>> That is what specification is for. >> >> Indeed. >> >>> How can an object implement [[Construct]] but not [[Call]]? >> >> It can if it is a host object and it has a [[Construct]] which is >> different from the one defined for native Function objects in ECMA-262. >> Then there is no need for it to have [[Call]]. > > And in fact, some built-in objects have behavior "when called as a > constructor" which cannot be explained as the 13.2.2 [[Construct]] algorithm > invoking their [[Call]] behavior. One example is the String constructor. The > spec doesn't seem to explicitly define its [[Call]] and [[Construct]] > internal properties, but this is the only sane interpretation. > This behavior is explainable by the fact that [[Construct]] always results in an object, even if the function that it called returns a primitive value. There is no constructor in the specification whose behavior cannot be explained by [[Call]] and [[Construct]]. We discussed this a bit in comp.lang.javascript thread "Using "new function() {...}" as a Singleton" (for the truly interested). This can be illustrated by an example. For those interested and willing to bear with typos (it's late; I'm tired), the following function returns a string value and yet when called as a constructor, an object is returned. function MyString(s) { if(this instanceof MyString) { this.toString = this.valueOf = function() { return String(s); }; } return String(s); } new MyString("foo"); // Object. MyString("bar"); // string value. This is explained by [[Construct]] in ECMA-262 Ed 3: 1. Create a new native ECMAScript object. 2. Set the [[Class]] property of Result(1) to "Object". 3. Get the value of the prototype property of F. 4. If Result(3) is an object, set the [[Prototype]] property of Result(1) to Result(3). 5. If Result(3) is not an object, set the [[Prototype]] property of Result(1) to the original Object prototype object as described in 15.2.3.1. 6. Invoke the [[Call]] property of F, providing Result(1) as the this value and providing the argument list passed into [[Construct]] as the argument values. 7. If Type(Result(6)) is Object then return Result(6). 8. Return Result(1). Garrett
Received on Friday, 8 October 2010 06:50:06 UTC