A read/write __proto__ that can vanish
Some people yearn hotly for __proto__, preferrably writable if at all possible, while others point to problems with security and software privacy. I get the impression that this could be solved by adding a fourth flag among the property flags Enumerable, Writable and Flexible. There might be a flag called Visible, so you could make __proto__ apparently vanish by setting Visible to false. As an added bonus, this solution would let code hide the prototype property on constructors if desired. Personally I'd love to see it defined in such a way that I could set prototype inheritance in a simple, straightforward way at the beginning of a constructor function: function $MyConstructor() { this.proto = MySuperInstance; // Here you can hide proto if desired. ... } If a visible proto is standardized, the name should be proto, not __proto__, in my opinion. The underscores indicate nonstandard. -- Ingvar von Schoultz --- (My quirky use of capitals in code comes from my opinion that reserved and predefined words should all start with lowercase, and user-defined should all start with uppercase, because this will easily and elegantly prevent a host of name-collision problems when things like programming languages are upgraded with new labels.) ___ Es4-discuss mailing list Es4-discuss@mozilla.org https://mail.mozilla.org/listinfo/es4-discuss
Re: A read/write __proto__ that can vanish
On Jul 16, 2008, at 10:29 AM, Ingvar von Schoultz wrote: Some people yearn hotly for __proto__, preferrably writable if at all possible, while others point to problems with security and software privacy. I wrote recently that __proto__ should be viewed as call/cc without macros for common use-case (and average users) -- too sharp and low- level a tool for a language like JS. I get the impression that this could be solved by adding a fourth flag among the property flags Enumerable, Writable and Flexible. There might be a flag called Visible, so you could make __proto__ apparently vanish by setting Visible to false. There's no point in Visible if the property could be deleted altogether. What would be the difference? Note that a proto or __proto__ property reflecting [[Prototype]] is *not* the same as the internal [[Prototype]] property, which would always be visible in the sense of checked by [[Get]], [[Put]], etc. We should not add property attributes that can mutate lightly. The motivation for __proto__ is suspect (I argue, base on our experience -- and I perpetrated __proto__ a long time ago). The need for Visible is non-existent IMHO, while the costs and ramifications of another single-bit attribute, one that causes the property to appear to be deleted, are undesirable. Visibility control over names is an important topic, but it can't be served by a single-bit attribute. ES4 as proposed has namespaces to serve (among other use-cases) the cheap and easily expressed private members use-case. That's not this __proto__ case, which anyway depends on a suspect predicate (the need for __proto__). Better to settle the predicate issue first, and avoid adding general mechanism prematurely. /be ___ Es4-discuss mailing list Es4-discuss@mozilla.org https://mail.mozilla.org/listinfo/es4-discuss
RE: A read/write __proto__ that can vanish
Personally, I don't that the internal [[Prototype]] property should reify as an actual property of the object. It's really a more fundamental aspect of objectness than regular properties. From that perspective, if you want to control access to it, it should probably be done as a flag on the object itself, much as the ES3.1 proposal does with the [[Extensible]] property. -Original Message- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Ingvar von Schoultz Sent: Wednesday, July 16, 2008 10:29 AM To: [EMAIL PROTECTED]; es4-discuss@mozilla.org Subject: A read/write __proto__ that can vanish Some people yearn hotly for __proto__, preferrably writable if at all possible, while others point to problems with security and software privacy. I get the impression that this could be solved by adding a fourth flag among the property flags Enumerable, Writable and Flexible. There might be a flag called Visible, so you could make __proto__ apparently vanish by setting Visible to false. As an added bonus, this solution would let code hide the prototype property on constructors if desired. Personally I'd love to see it defined in such a way that I could set prototype inheritance in a simple, straightforward way at the beginning of a constructor function: function $MyConstructor() { this.proto = MySuperInstance; // Here you can hide proto if desired. ... } If a visible proto is standardized, the name should be proto, not __proto__, in my opinion. The underscores indicate nonstandard. -- Ingvar von Schoultz --- (My quirky use of capitals in code comes from my opinion that reserved and predefined words should all start with lowercase, and user-defined should all start with uppercase, because this will easily and elegantly prevent a host of name-collision problems when things like programming languages are upgraded with new labels.) ___ Es4-discuss mailing list Es4-discuss@mozilla.org https://mail.mozilla.org/listinfo/es4-discuss ___ Es4-discuss mailing list Es4-discuss@mozilla.org https://mail.mozilla.org/listinfo/es4-discuss
Re: A read/write __proto__ that can vanish
Ingvar von Schoultz wrote: Some people yearn hotly for __proto__, preferrably writable if at all possible, while others point to problems with security and software privacy. I get the impression that this could be solved by adding a fourth flag among the property flags Enumerable, Writable and Flexible. There might be a flag called Visible, so you could make __proto__ apparently vanish by setting Visible to false. Adding switches like this is making code too complicated and will result in plenty of arguments about whether a particular class should have the switch turned on or off. Often the classes you want to use will have it set the wrong way, leading to more balkanization of libraries. In the committee we've already spent too much time discussing which properties should be enumerable, dontDelete, etc., and we still get those wrong at times. Waldemar ___ Es4-discuss mailing list Es4-discuss@mozilla.org https://mail.mozilla.org/listinfo/es4-discuss
Re: A read/write __proto__ that can vanish
Brendan Eich wrote: There's no point in Visible if the property could be deleted altogether. What would be the difference? Oops! Sorry! Lacking low-level insight I didn't think of that. So my idea has no bearing at all on the inherent problems, much less solved them. Too bad. That's not this __proto__ case, which anyway depends on a suspect predicate (the need for __proto__). Better to settle the predicate issue first, and avoid adding general mechanism prematurely. I think the only situation where I repeatedly feel a real, serious need for something like a writable __proto__ is the one I showed. Specifying inheritance is too spread out and too intricate. Most of all I want the constructor to define its own inheritance, not some outside code. Having to set .prototype in an unrelated expression outside, with the constructor reduced to a powerless bystander, feels like I'm writing a goto. It's too unstructured. Is your objection to __proto__ similar to this? Is __proto__ an inheritance goto? If that's the kind of problem it creates I agree that it doesn't belong in this language. If that's the case, would a writable __proto__ become well- structured if it could be accessed only from inside the constructor, and not by any other code? That's the only way I'd use it anyway. I'd love to have constructors that could write to their [[Prototype]]. But if that isn't possible I'd be almost as happy if we simply had the option to set both the prototype and its constructor property in one compound statement: function $MyConstructor() prototype MySuperInstance { ... } For me this would generally be the best arrangement, and I suppose it's the same for most people. Not having analyzed all the details, it /seems/ to me that the ideal would be that the above syntax lock and hide [[Prototype]], while a different syntax for exotic use would allow the constructor added freedom. -- Ingvar von Schoultz --- (My quirky use of capitals in code comes from my opinion that reserved and predefined words should all start with lowercase, and user-defined should all start with uppercase, because this will easily and elegantly prevent a host of name-collision problems when things like programming languages are upgraded with new labels.) ___ Es4-discuss mailing list Es4-discuss@mozilla.org https://mail.mozilla.org/listinfo/es4-discuss
Re: 13.2.2 [[Construct]], constructor, and [[Class]] (was __proto__)
On Dec 14, 2007, at 12:50 PM, P T Withington wrote: On 2007-09-23, at 14:14 EDT, Brendan Eich wrote: The reason for the original prototype-owned constructor was to afford a back-pointer from prototype to constructor function without imposing a per-instance property (which could be optimized to be shared where possible, overridden where desired -- but at some cost in implementation complexity). I'm not convinced it's worth changing this for ES4. Anyway it is very late to have a new proposal -- we are finalizing proposals next week at the face-to-face meeting. So, was nothing done about this? We're starting to work on an es4 back-end for our stuff and running into this issue. We can make sure all our constructors give each instance a constructor slot (and we can smash the class prototype.constructor to point to the superclass) as we do for our es3 back end; but I was really hoping for a cleaner solution in es4. Nothing's changed, no proposal that avoids per-instance overhead or more complicated implementation strategies to avoid that. There's also an entrainment hazard, not huge but non-zero risk of introducing leaks into existing web apps if we entrain the constructor where the web app code intentionally clears prototype.constructor (which is read/write). The constructor property is and always was intended to be a property of the prototype, not of each instance. Changing that now is hard. The merits are not compelling enough IMHO. Is there some other way in es4 that from an instance one can navigate up the superclass chain? Can I say: super.constructor perhaps, to find my class's superclass? For a class C, C.prototype.constructor is indeed C. But super does not work that way -- it's used for invoking the super-class constructor, rather: class B { var x;function B(x) : x=x {} } new B(2).x 2 class D extends B { var y; function D(x,y) : y=y, super(x) {} } d = new D(3,4) [object D] d.x 3 d.y 4 To reflect on inheritance and other relations, use the meta-objects interfaces: http://wiki.ecmascript.org/doku.php?id=proposals:meta_objects Given class C: let Ctype = reflect::typeOf(C); for (let Csup in Ctype.superTypes()) { // Csup is a base class or interface of C here } /be___ Es4-discuss mailing list Es4-discuss@mozilla.org https://mail.mozilla.org/listinfo/es4-discuss
Re: __proto__
On 2007-09-22, at 17:52 EDT, liorean wrote: Which could be done, of course, it should be a simple thing to add that in the algorithm for [[Construct]]. But then we have the question of what to do with constructors that return other objects than that set up by steps 1 through 5 of the [[Construct]] algorithm. A constructor can return other objects, you know. You'd have to decide whether this property should be set up prior to step 6 in the algorithm or subsequent to step 7. If prior, only the original object that was created in step 1 gets it, if subsequent, return values get it even if they are not the same as the original object. Dylan has a rule that the constructor must return an object that is a subtype of the constructor. If that were enforced, I would see no reason to reset the constructor property of the returned object. Actually, I think this would be a nice and simple fix to ES3 that probably wouldn't hurt much code out there. Agreed. As I mentioned elsewhere in this thread, we do this manually in our framework for now. ___ Es4-discuss mailing list Es4-discuss@mozilla.org https://mail.mozilla.org/listinfo/es4-discuss
Re: 13.2.2 [[Construct]], constructor, and [[Class]] (was __proto__)
On 9/22/07, liorean [EMAIL PROTECTED] wrote: On 22/09/2007, Garrett Smith [EMAIL PROTECTED] wrote: What I've found is that it's always giving wrong constructor property with inheritance chains. A -- B -- C c = (new C).constructor;// A snip I meant an enumerable superclass property! You get that if you do the following: function A(){} function B(){} B.prototype=new A; function C(){} C.prototype=new B; Because if you do that, you replace the prototype containing the original constructor property (e.g. a reference back to the function C) with an instance of another constructor (e.g. B), but that instance doesn't have the constructor property that the original prototype had. If you want to keep the constructor properties, you need to do that manually. (With the obvious result that then the constructor property will be enumerable. Which can be changed through adding a call on propertyIsEnumerable in ES4.) Ah, sorry, I said a few things wrong! 1. constructor is DontEnum.13.2 - http://bclary.com/2004/11/07/#a-13.2 (It's the user-defined superclass property that is enumerable.) 1. The constructor property should be on the object instance *created* by the function. snip How about a constructor property on the function instance? 2. (new function(){}).constructor should be Function. But you understood what I meant even though I said it wrong. I meant to say that the object instance's constructor property should be the Function that new was called on. Which could be done, of course, it should be a simple thing to add that in the algorithm for [[Construct]]. But then we have the question of what to do with constructors that return other objects than that set up by steps 1 through 5 of the [[Construct]] algorithm. A constructor can return other objects, you know. snip In ES4, it is a syntax error to specify a result type of a constructor. If someone is using new F, the constructor property of the instance should be F. (new F).constructor; // should be F. The constructor property should match the [[Construct]] property. This should happen right before the prototype. Here's 13.2.2 with my edits: 13.2.2 [[Construct]] When the [[Construct]] property for a Function object F is called, the following steps are taken: 1. Create a new native ECMAScript object. 2. Set the [[Class]] property of Result(1) to Object. -- ∆ set the [[Class]] of o to reflect the name F -- 3. Get the value of the prototype property of F. -- Set the constructor property of Result(1) to 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). ∆ Note: Although allowed in ES3, Functions used as constructors should not return a value. (reword) probably wouldn't hurt much code out there. What could it hurt? What would get broken? Benefits: 1) can crawl up the constructors without having to bake the functionality into your library, 2) Doesn't force clients to use a non-standard fix. 3) [[class]] matches constructor property The flip side of (2) is that if it stays, a client of a library that fixes the constructor property may have objects created by an in-house or another third party library where the library doesn't fix the constructor property. The constructor property is modifiable, but you cant count on third party libraries using the same modification (I call it a nonstandard fix) to the constructor property. ES4 ref impl seems a bit off: (new function F(){}).constructor [function Function] new Date(9e9).constructor [class Class] 1['constructor'] [class Class] It appears that es4 ref impl has the correct result for instancof on primitives All are true in ES4 and false in ES3: true instanceof Boolean oo instanceof String 2 instanceof Number null instanceof Object NaN instanceof Number Number.Infinity instanceof Number I think the change is correct. if typeof b == boolean, b instanceof boolean seems like it must be true. I would like to understand why it was not working right in ES3-, if someone can explain. Garrett David liorean Andersson ___ Es4-discuss mailing list Es4-discuss@mozilla.org https://mail.mozilla.org/listinfo/es4-discuss
Re: 13.2.2 [[Construct]], constructor, and [[Class]] (was __proto__)
On 23/09/2007, Garrett Smith [EMAIL PROTECTED] wrote: 2. (new function(){}).constructor should be Function. On Sep 23, 2007, at 8:59 AM, liorean wrote: I agree. And in ES3 it is, unless the function either: On 23/09/2007, Brendan Eich [EMAIL PROTECTED] wrote: No: js (new function(){}).constructor function () { } js function C(){} js new C().constructor function C() { } Ah, my mistake there, was thinking of (function(){}).constructor for a moment there. in no case is the value of (new function(){}).constructor Function. Thinking about it with the new keyword in mind, I just realise that what Garrett suggested makes no sense anyway - the function object is the constructor. The function object is an instance of Function, but the resulting object is an instance of the function object. Making the object have Function as it's constructor property breaks the prototype-constructor relationship. On 23/09/2007, Garrett Smith [EMAIL PROTECTED] wrote: It appears that es4 ref impl has the correct result for instancof on primitives On Sep 23, 2007, at 8:59 AM, liorean wrote: A bugfix, IIRC. On 23/09/2007, Brendan Eich [EMAIL PROTECTED] wrote: Incompatbile enough that we are not taking the chance -- we are changing this to match ES1-3, and to avoid boolean : Boolean etc. Sad to hear that, but I guess compatibility will have to rule here. -- David liorean Andersson ___ Es4-discuss mailing list Es4-discuss@mozilla.org https://mail.mozilla.org/listinfo/es4-discuss
Re: 13.2.2 [[Construct]], constructor, and [[Class]] (was __proto__)
On 9/23/07, liorean [EMAIL PROTECTED] wrote: On 23/09/2007, Garrett Smith [EMAIL PROTECTED] wrote: 2. (new function(){}).constructor should be Function. On Sep 23, 2007, at 8:59 AM, liorean wrote: I agree. And in ES3 it is, unless the function either: On 23/09/2007, Brendan Eich [EMAIL PROTECTED] wrote: No: js (new function(){}).constructor function () { } js function C(){} js new C().constructor function C() { } Ah, my mistake there, was thinking of (function(){}).constructor for a moment there. in no case is the value of (new function(){}).constructor Function. It shouldn't be, but it is in OSX Ref Impl. (I did not build this). js (new function(){}).constructor [function Function] Thinking about it with the new keyword in mind, I just realise that what Garrett suggested makes no sense anyway - the function object is the constructor. The function object is an instance of Function, but the resulting object is an instance of the function object. Making the object have Function as it's constructor property breaks the prototype-constructor relationship. Correctly corrected. In the following example: function F(){} F.prototype.constructor = F; F.prototype.propertyIsEnumerable(constructor); // false, it's set to {DontEnum} in step 10. Object.prototype. F.prototype.constructor === F; //true F.prototype = { constructor : F }; F.prototype.constructor === F; // false F.prototype.propertyIsEnumerable(constructor); // true, now F.prototype is an object F.prototype is assigned to a new Object. The new Object goes through [[construct]] getting its [[class]] property to Object. Object instances get the constructor property from Object.prototype. The only exception being prototype properties of Function objects, where the constructor is flagged DontEnum. The constructor property of an object doesn't reflect the constructor that called it. Garrett On 23/09/2007, Garrett Smith [EMAIL PROTECTED] wrote: It appears that es4 ref impl has the correct result for instancof on primitives On Sep 23, 2007, at 8:59 AM, liorean wrote: A bugfix, IIRC. On 23/09/2007, Brendan Eich [EMAIL PROTECTED] wrote: Incompatbile enough that we are not taking the chance -- we are changing this to match ES1-3, and to avoid boolean : Boolean etc. Sad to hear that, but I guess compatibility will have to rule here. So it's going back, to (true instanceof Boolean == false), huh ? -- David liorean Andersson ___ Es4-discuss mailing list Es4-discuss@mozilla.org https://mail.mozilla.org/listinfo/es4-discuss
Re: 13.2.2 [[Construct]], constructor, and [[Class]] (was __proto__)
On 23/09/2007, Garrett Smith [EMAIL PROTECTED] wrote: Function objects get a non-enumerable constructor. function F(){}; F.constructor === Function; // true F.prototype.hasOwnProperty('constructor'); //true F.prototype.propertyIsEnumerable(constructor); // false. Of course. Object instances don't, unless it's a prototype object created by [[construct]] (new F).constructor === F.constructor; // true. Undesirable Wrong, it's false. (new F).constructor === F.constructor; // = false (new F).constructor === F.prototype.constructor; // = true This works fine for shallow inheritance Objects don't get a constructor In what way do you mean they don't? Their constructor is the Object object, as you show next: ({}).constructor === Object.prototype.constructor; // True. On 23/09/2007, Garrett Smith [EMAIL PROTECTED] wrote: 1. The constructor property should be on the object instance *created* by the function. On 9/23/07, liorean [EMAIL PROTECTED] wrote: That argument I agree with. It should be on the instance and not the prototype. On 23/09/2007, Garrett Smith [EMAIL PROTECTED] wrote: Which is different from the way built ins work, but seems OK. Well, at least if you want to make sense out of the prototypal inheritance scheme. The built ins are all single level IIRC,k and don't need to set up their prototype relationship in user code. A prototype system that didn't just clobber the old prototype when setting up prototype chains maybe could have done it better. But that won't happen in ECMAScript. On 23/09/2007, Garrett Smith [EMAIL PROTECTED] wrote: 2. (new function(){}).constructor should be Function. On 9/23/07, liorean [EMAIL PROTECTED] wrote: I agree. Actually I don't agree here, see my reply to Brendan earlier. And in ES3 it is, unless the function either: And I was thinking of (function(){}).constructor here, not (new function(){}).constructor, when I said in ES3 it is. It isn't, which is proper since the object is constructed by the anonymous function object, not the Function object. On 23/09/2007, Garrett Smith [EMAIL PROTECTED] wrote: When there is an anonymous constructor, we have the ability to get at the constructor property. I don't see this as a problem - the constructor property should be the function that actually constructed the object. Since ES3 allows any value (except eval, I think) to be assigned to any variable (except read only ones and those with special setters), the difference between function declarations and function expressions is that declarations are *by default* accessible through a variable name only, and function expressions are *by default* accessible through the return value of the expression only. There's no way to actually tell a function derived from a function expression and a function derived from a function declaration apart after the fact. (Well, except for that function expressions make the name optional.) So, if we want to be able to get at constructors at all, we can't distinguish between how functions are derived - either we provide the functionality, or we don't. function Animation(element){ var looped = 0; var e = element; function construct() { this.loopCount = function() { return looped; } this.loop = function() { looped++; } } return new construct(); } new new Animation().constructor().constructor; // construct Sure. It's a closure, it exposes a property it's told to expose. (If you use the new keyword, that it exposes the function object as the constructor property of the constructed object should be expected.) You can do this without the new keyword if you want to not expose the function object, or use the delete keyword to explicitly remove it. On 9/23/07, liorean [EMAIL PROTECTED] wrote: A disagreement of terminology I think. If you ask me, a function instance is a function object. When using a function instance as a constructor, you create an instance of that constructor (== function instance) which is a plain, ordinary, mundane, normal, run-of-the-mill, typical object. (Agh, ran out of synonyms!) On 23/09/2007, Garrett Smith [EMAIL PROTECTED] wrote: F is a Function instance f is a function instance The terminology is confusing. F is an instance of Function f is an instance of F Function is a function object F is a function object f is an object As I see it, the meaning of function instance is an object that is function-like, in other words a function object or a special host object (like Function.prototype, which is a function but not an instance of Function). -- David liorean Andersson ___ Es4-discuss mailing list Es4-discuss@mozilla.org https://mail.mozilla.org/listinfo/es4-discuss
Re: 13.2.2 [[Construct]], constructor, and [[Class]] (was __proto__)
On 9/23/07, liorean [EMAIL PROTECTED] wrote: On 23/09/2007, Garrett Smith [EMAIL PROTECTED] wrote: Function objects get a non-enumerable constructor. function F(){}; F.constructor === Function; // true F.prototype.hasOwnProperty('constructor'); //true F.prototype.propertyIsEnumerable(constructor); // false. Of course. F.prototype = { constructor : F } F.prototype.propertyIsEnumerable(constructor); Object instances don't, unless it's a prototype object created by [[construct]] (new F).constructor === F.constructor; // true. Undesirable Wrong, it's false. (new F).constructor === F.constructor; // = false (new F).constructor === F.prototype.constructor; // = true Right. This works fine for shallow inheritance Objects don't get a constructor In what way do you mean they don't? Their constructor is the Object object, as you show next: ({}).constructor === Object.prototype.constructor; // True. ({}).hasOwnProperty(constructor); //false. {} is the same as new Object; new Object goes through [[construct]] The instance does not get a constructor property. No object instance does. Well, none except objects that are prototype properties that went through [[construct]]. This is confusing and makes the language less clear to developers. It confuses me. On 23/09/2007, Garrett Smith [EMAIL PROTECTED] wrote: 1. The constructor property should be on the object instance *created* by the function. On 9/23/07, liorean [EMAIL PROTECTED] wrote: That argument I agree with. It should be on the instance and not the prototype. On 23/09/2007, Garrett Smith [EMAIL PROTECTED] wrote: Which is different from the way built ins work, but seems OK. Well, at least if you want to make sense out of the prototypal inheritance scheme. The built ins are all single level IIRC,k and don't need to set up their prototype relationship in user code. A prototype system that didn't just clobber the old prototype when setting up prototype chains maybe could have done it better. But that won't happen in ECMAScript. I don't see a problem. var d = new Date; d.constructor == Date; // true d.hasOwnProperty('constructor'); // false The proposed change would have the result of: d.hasOwnProperty('constructor'); // true d.isPropertyEnumerable('constructor'); // false On 23/09/2007, Garrett Smith [EMAIL PROTECTED] wrote: 2. (new function(){}).constructor should be Function. On 9/23/07, liorean [EMAIL PROTECTED] wrote: I agree. Actually I don't agree here, see my reply to Brendan earlier. Right. On 23/09/2007, Garrett Smith [EMAIL PROTECTED] wrote: When there is an anonymous constructor, we have the ability to get at the constructor property. I don't see this as a problem - Right. Whether or not the Function object has a name is irrelevant. the constructor property should be the function that actually constructed the object. Exactly. That's what I'm talking about. The fact that (new C).constructor === A; is true, by default of the language, is counterintuitive. [[construct]] gives a function instance a special prototype property. That prototype property is an object, but not just an object, a special object -- one that has a constructor property that is specially flagged DontEnum. You lose that property the moment you give a prototype property to F. Well, if the prototype property you give to F is created through [[construct]], you don't. You have to be careful. F=function(){}; new F().constructor == F; // true. F.propertyIsEnumerable(prototype); //true, Futhark and JScript say false. F.prototype = {}; new F().constructor == F; // false. F.prototype.constructor = F; F.prototype.propertyIsEnumerable(constructor); // true, JScript says false. var complaint = false; for( var prop in new F ) complaint = true; if(!complaint) alert('failure'); The browser support is pretty inconsistent, too. So, if we want to be able to get at constructors at all, we can't distinguish between how functions are derived - either we provide the functionality, or we don't. function expression/declaration, new Function -- the constructor should all be Function function FF(){} FF.constructor === Function; // true (Function()).constructor === Function; // true. (new Function()).constructor === Function; // true. The Object instance that is created in [[construct]] could have the constructor property as DontEnum. This seems to be a compatibility issue with ES3. In ES3, you can't depend on the enumerability of an object's own constructor property. This is because prototype objects have a constructor property that is flagged DontEnum. The idea is to make constructor a DontEnum property on all objects. (not just ones that were created through [[construct]] to be used as prototype properties). constructor would be a default value given to the object in [[construct]] What do you think? F is an instance of Function f is an instance of F Function
Re: 13.2.2 [[Construct]], constructor, and [[Class]] (was __proto__)
On Sep 23, 2007, at 12:22 PM, Garrett Smith wrote: in no case is the value of (new function(){}).constructor Function. It shouldn't be, but it is in OSX Ref Impl. (I did not build this). js (new function(){}).constructor [function Function] No, that's just http://bugs.ecmascript.org/ticket/64 -- proof: (new function(){}).constructor [function Function] (new function(){}).constructor === Function false f = function(){} [function Function] (new f).constructor === f true With Function.prototype.toString buggy, you need to test identity of function objects. /be ___ Es4-discuss mailing list Es4-discuss@mozilla.org https://mail.mozilla.org/listinfo/es4-discuss
Re: 13.2.2 [[Construct]], constructor, and [[Class]] (was __proto__)
On 9/23/07, Brendan Eich [EMAIL PROTECTED] wrote: On Sep 23, 2007, at 12:22 PM, Garrett Smith wrote: in no case is the value of (new function(){}).constructor Function. It shouldn't be, but it is in OSX Ref Impl. (I did not build this). js (new function(){}).constructor [function Function] No, that's just http://bugs.ecmascript.org/ticket/64 -- proof: (new function(){}).constructor [function Function] (new function(){}).constructor === Function false f = function(){} [function Function] (new f).constructor === f true Ah, OK. js Function().toSource() function(){} Works. I usually like modifying toString anyway. F = function(){}; F.prototype = { toString : function() { return Fork!; } }; f = new F; f.toString() //f.constructor With Function.prototype.toString buggy, you need to test identity of function objects. Buggy or not, since functions could have different [[Scope]], testing toString makes no sense. Testing toSource is useful for seeing if it's a native function (eval, or RegExp test), but Function.prototype.toSource() isn't provided in the spec and isn't supported in JScript. Garrett /be -- Programming is a collaborative art. ___ Es4-discuss mailing list Es4-discuss@mozilla.org https://mail.mozilla.org/listinfo/es4-discuss
Re: __proto__
Is __proto__ somehow a new security threat? __proto__ has been around for ages in SM/FF and not only that, but it has been there in the more hazardous writable form. I just wanted it be actually included in the spec. Or is there some new functionality in ES4 that will somehow interact with __proto__ to introduce a security threat? Kris - Original Message - From: Lars T Hansen [EMAIL PROTECTED] To: Kris Zyp [EMAIL PROTECTED] Cc: Brendan Eich [EMAIL PROTECTED]; liorean [EMAIL PROTECTED]; es4-discuss@mozilla.org Sent: Tuesday, September 11, 2007 2:34 AM Subject: Re: __proto__ On the one hand, __proto__ is another potential security hole, and it prevents implementations from sharing prototype objects among multiple documents -- the link may be read-only but the object isn't. Function B called from function A with object O may hack O.__proto__ and A can do nothing about it; suddenly all O-like objects in the system act differently. On the other hand, Constructor.prototype is generally available for any Constructor, so it's hard to see what the real damage is -- it's not obviously worse than some other aspects of the language. On the third hand, some implementations may have specialized objects for which no Constructor is available and for whom keeping [[Prototype]] unavailable is desirable. Similarly, some toolkits may have private prototype objects that are not available to client code because the constructor is hidden in a lexical scope (ES3) or package/namespace (ES4). Introspection is great, but it assumes a lot about how trust works in the environment. --lars On 9/11/07, Kris Zyp [EMAIL PROTECTED] wrote: The alternative above would standardize read-only __proto__, which would make that property no longer implementation-specific. But of course we have no proposal to do that. I realize this wasn't really the main subject... but could the __proto__ property be defined in the spec (as readonly)? I would love to see that property standardized. Kris ___ Es4-discuss mailing list Es4-discuss@mozilla.org https://mail.mozilla.org/listinfo/es4-discuss ___ Es4-discuss mailing list Es4-discuss@mozilla.org https://mail.mozilla.org/listinfo/es4-discuss
Re: __proto__
__proto__ breaks abstraction boundaries in the language -- it's just like function.caller, you get to look at and change objects that your caller may wish to keep secret from you. Whether it's actually a security threat depends on the details of the environment: whether your caller fits those criteria or not, or whether your run-time environment has objects whose constructors are not exposed to client code. --lars On 9/11/07, Kris Zyp [EMAIL PROTECTED] wrote: Is __proto__ somehow a new security threat? __proto__ has been around for ages in SM/FF and not only that, but it has been there in the more hazardous writable form. I just wanted it be actually included in the spec. Or is there some new functionality in ES4 that will somehow interact with __proto__ to introduce a security threat? Kris - Original Message - From: Lars T Hansen [EMAIL PROTECTED] To: Kris Zyp [EMAIL PROTECTED] Cc: Brendan Eich [EMAIL PROTECTED]; liorean [EMAIL PROTECTED]; es4-discuss@mozilla.org Sent: Tuesday, September 11, 2007 2:34 AM Subject: Re: __proto__ On the one hand, __proto__ is another potential security hole, and it prevents implementations from sharing prototype objects among multiple documents -- the link may be read-only but the object isn't. Function B called from function A with object O may hack O.__proto__ and A can do nothing about it; suddenly all O-like objects in the system act differently. On the other hand, Constructor.prototype is generally available for any Constructor, so it's hard to see what the real damage is -- it's not obviously worse than some other aspects of the language. On the third hand, some implementations may have specialized objects for which no Constructor is available and for whom keeping [[Prototype]] unavailable is desirable. Similarly, some toolkits may have private prototype objects that are not available to client code because the constructor is hidden in a lexical scope (ES3) or package/namespace (ES4). Introspection is great, but it assumes a lot about how trust works in the environment. --lars On 9/11/07, Kris Zyp [EMAIL PROTECTED] wrote: The alternative above would standardize read-only __proto__, which would make that property no longer implementation-specific. But of course we have no proposal to do that. I realize this wasn't really the main subject... but could the __proto__ property be defined in the spec (as readonly)? I would love to see that property standardized. Kris ___ Es4-discuss mailing list Es4-discuss@mozilla.org https://mail.mozilla.org/listinfo/es4-discuss ___ Es4-discuss mailing list Es4-discuss@mozilla.org https://mail.mozilla.org/listinfo/es4-discuss