Re: Setting a property in the prototype chain?

2011-04-12 Thread Erik Arvidsson
On Tue, Apr 12, 2011 at 08:41, Allen Wirfs-Brock  wrote:
> In ES5
>  {}.valueOf.call(undefined)
> doesn't yield the this object. In general, ES5 built-ins do not convert their 
> this parameter to the global object when it is undefined.

FYI

http://code.google.com/p/v8/issues/detail?id=1321
https://bugs.webkit.org/show_bug.cgi?id=58338

-- 
erik
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Setting a property in the prototype chain?

2011-04-12 Thread Allen Wirfs-Brock

On Apr 12, 2011, at 12:57 AM, Lasse Reichstein wrote:
> 
> In that case, why not just
>  obj = Object(obj);
> 
> It has the added advantage of not returning the global object for null and 
> undefined,
> but just a plain new object (although either can be said to be wrong in this 
> case).

I used {}.valueOf in order to avoid converting null and undefined to a new 
object which would then be used as the starting point of the lookup.

In ES5
  {}.valueOf.call(undefined)
doesn't yield the this object. In general, ES5 built-ins do not convert their 
this parameter to the global object when it is undefined.

Allen


___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Setting a property in the prototype chain?

2011-04-12 Thread Mark S. Miller
On Tue, Apr 12, 2011 at 3:57 AM, Lasse Reichstein <
reichsteinatw...@gmail.com> wrote:

> On Tue, 12 Apr 2011 07:55:26 +0200, Allen Wirfs-Brock <
> al...@wirfs-brock.com> wrote:
>
>
>> On Apr 11, 2011, at 6:45 PM, Axel Rauschmayer wrote:
>>
>>  var obj={}.valueOf.call(obj);  // ToObject in case primitive value passed

>>> ...
>
>  {}.valueOf  is the same value as Object.prototype.valueOf assuming none of
>> the standard definitions have been over-written.  See the comment thread of
>> http://www.wirfs-brock.com/allen/posts/166 for a debate as to which of
>> these forms is more or less optimizable.
>>
>> Object.prototype.valueOf as specified is essentially a call to the
>> internal ToObject operation that wrappers primitive values. I put it in to
>> deal with cases like getDefiningObject("some string", "match")
>>
>
>
> In that case, why not just
>  obj = Object(obj);
>
> It has the added advantage of not returning the global object for null and
> undefined,
>

For null and undefined, Object.prototype.valueOf throws. It does not return
the global object.



> but just a plain new object (although either can be said to be wrong in
> this case).
>
> /L
> --
> Lasse Reichstein - reichsteinatw...@gmail.com
>
> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>



-- 
Cheers,
--MarkM
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Setting a property in the prototype chain?

2011-04-12 Thread Axel Rauschmayer
> Object.prototype.valueOf as specified is essentially a call to the internal 
> ToObject operation that wrappers primitive values. I put it in to deal with 
> cases like getDefiningObject("some string", "match")

Oh my, I've just consulted the ECMAScript spec and it's true. But isn't that 
counter-intuitive?

- Object.prototype.valueOf: convert to object
- String.prototype.valueOf: convert to primitive (for instances of String and 
primitive strings)
- Number.prototype.valueOf: same as above, but for numbers
- etc.

Even if that can't be fixed any more, there could be a method Object.toObject() 
with more obvious semantics. I try to avoid "expert magic" when using a 
programming language and it seems like a shame that this kind of magic is 
necessary here ( {} and valueOf()).

Greetings,

Axel

-- 
Dr. Axel Rauschmayer

a...@rauschma.de
twitter.com/rauschma

home: rauschma.de
blog: 2ality.com



___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Setting a property in the prototype chain?

2011-04-12 Thread Lasse Reichstein
On Tue, 12 Apr 2011 07:55:26 +0200, Allen Wirfs-Brock  
 wrote:




On Apr 11, 2011, at 6:45 PM, Axel Rauschmayer wrote:

var obj={}.valueOf.call(obj);  // ToObject in case primitive value  
passed

...
{}.valueOf  is the same value as Object.prototype.valueOf assuming none  
of the standard definitions have been over-written.  See the comment  
thread of http://www.wirfs-brock.com/allen/posts/166 for a debate as to  
which of these forms is more or less optimizable.


Object.prototype.valueOf as specified is essentially a call to the  
internal ToObject operation that wrappers primitive values. I put it in  
to deal with cases like getDefiningObject("some string", "match")



In that case, why not just
  obj = Object(obj);

It has the added advantage of not returning the global object for null and  
undefined,
but just a plain new object (although either can be said to be wrong in  
this case).


/L
--
Lasse Reichstein - reichsteinatw...@gmail.com
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Setting a property in the prototype chain?

2011-04-11 Thread Allen Wirfs-Brock

On Apr 11, 2011, at 6:45 PM, Axel Rauschmayer wrote:

>> var obj={}.valueOf.call(obj);  // ToObject in case primitive value passed
> 
> Can you explain how this works?
> 
> - Why {} and not Object.prototype?
> 
> - I know valueOf as a method that returns a primitive if an object can be 
> converted to one and |this|, otherwise. Oddly enough, this works both in 
> strict mode and in non-strict mode, as explained in the comment.
> 
{}.valueOf  is the same value as Object.prototype.valueOf assuming none of the 
standard definitions have been over-written.  See the comment thread of 
http://www.wirfs-brock.com/allen/posts/166 for a debate as to which of these 
forms is more or less optimizable.

Object.prototype.valueOf as specified is essentially a call to the internal 
ToObject operation that wrappers primitive values. I put it in to deal with 
cases like getDefiningObject("some string", "match")

Allen___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Setting a property in the prototype chain?

2011-04-11 Thread Axel Rauschmayer
> var obj={}.valueOf.call(obj);  // ToObject in case primitive value passed

Can you explain how this works?

- Why {} and not Object.prototype?

- I know valueOf as a method that returns a primitive if an object can be 
converted to one and |this|, otherwise. Oddly enough, this works both in strict 
mode and in non-strict mode, as explained in the comment.

Thanks!

Axel

-- 
Dr. Axel Rauschmayer

a...@rauschma.de
twitter.com/rauschma

home: rauschma.de
blog: 2ality.com



___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Setting a property in the prototype chain?

2011-04-11 Thread Brendan Eich
On Apr 11, 2011, at 9:21 PM, David Bruant wrote:

> Actually I was wrong I think. With the introduction of proxies, ES
> engines won't be able to trivially prevent pd allocation as they could
> with regular objects just based on static analysis (since static
> analysis will often fail at saying whether the function will be used
> with regular objects or proxies as first argument)

Static analysis is conservative, yes. But type inference often can say what 
exact types |this| and other arguments have.

Anyway, this isn't about absolute guarantees unless JS provides an API to query 
without allocating :-P.


> I think it could be possible if we had a native Object.hasOwnProperty
> method since that's really what we need here (that's what a static
> analysis optimization would do internally).

That was left out on purposes during ES3.1/ES5 design to keep things minimal. 
And of course Proxies built on that API. So probably we should leave this as an 
optimization challenge (GC, type inference, both if possible).

/be
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Setting a property in the prototype chain?

2011-04-11 Thread David Bruant
Le 11/04/2011 22:01, Brendan Eich a écrit :
> On Apr 11, 2011, at 8:58 PM, David Bruant wrote:
>
>> Le 11/04/2011 21:47, Brendan Eich a écrit :
>>> On Apr 11, 2011, at 6:36 PM, Allen Wirfs-Brock wrote:
>>>
 Personally, I prefer Object.getOwnPropertyDescriptor as a property 
 existence test because it doesn't have the reflection the meta-circularity 
 concern.  I would write Dave's original function as: 

 function getDefiningObject(obj, key) {
  var obj={}.valueOf.call(obj);  // ToObject in case primitive value passed
  while (obj) {
 if (Object.getOwnPropertyDescriptor(obj,key)) return obj;
 obj =  Object.getPrototypeOf(obj);
  }
  throw new Error("key " + key + " not found");
 }
>>> Then the only downside is the pd allocation. Any way to avoid that?
>> Could static analysis help out to detect that the object is not going to
>> be used and consequently avoid the allocation?
> Of course, but that's a bit much and unless it is adopted by all the "bigs", 
> web developers won't count on it and may shy away from the allocation (based 
> on real measurements or premature optimization, doesn't matter).
Actually I was wrong I think. With the introduction of proxies, ES
engines won't be able to trivially prevent pd allocation as they could
with regular objects just based on static analysis (since static
analysis will often fail at saying whether the function will be used
with regular objects or proxies as first argument)


> It's not the end of the world to have a pd allocation, of course. But an API 
> that avoids it without analysis might be worth considering.
I think it could be possible if we had a native Object.hasOwnProperty
method since that's really what we need here (that's what a static
analysis optimization would do internally).

David
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Setting a property in the prototype chain?

2011-04-11 Thread Allen Wirfs-Brock

On Apr 11, 2011, at 12:47 PM, Brendan Eich wrote:
>> 
> 
> Then the only downside is the pd allocation. Any way to avoid that?
> 
> /be

Use a GC that supports cheap allocation/recovery of short-lived objects :-)

It's probably premature optimization to worry about that one pd allocation 
without knowing more about the actual use case.   I suspect that in many cases, 
the caller would actually want to get the pd back and so it would probably be 
best to return: {object: obj, desc: pd}.  Of course that has yet another 
ephemeral object allocation. But really, if you over worry about such 
allocations you end up doing FORTRAN-like coding.

Maybe it's time to work on some JavaScript ephemeral GC benchmarks...

Allen___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Setting a property in the prototype chain?

2011-04-11 Thread Brendan Eich
On Apr 11, 2011, at 8:58 PM, David Bruant wrote:

> Le 11/04/2011 21:47, Brendan Eich a écrit :
>> On Apr 11, 2011, at 6:36 PM, Allen Wirfs-Brock wrote:
>> 
>>> Personally, I prefer Object.getOwnPropertyDescriptor as a property 
>>> existence test because it doesn't have the reflection the meta-circularity 
>>> concern.  I would write Dave's original function as: 
>>> 
>>> function getDefiningObject(obj, key) {
>>>  var obj={}.valueOf.call(obj);  // ToObject in case primitive value passed
>>>  while (obj) {
>>> if (Object.getOwnPropertyDescriptor(obj,key)) return obj;
>>> obj =  Object.getPrototypeOf(obj);
>>>  }
>>>  throw new Error("key " + key + " not found");
>>> }
>> Then the only downside is the pd allocation. Any way to avoid that?
> Could static analysis help out to detect that the object is not going to
> be used and consequently avoid the allocation?

Of course, but that's a bit much and unless it is adopted by all the "bigs", 
web developers won't count on it and may shy away from the allocation (based on 
real measurements or premature optimization, doesn't matter).

It's not the end of the world to have a pd allocation, of course. But an API 
that avoids it without analysis might be worth considering.

/be
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Setting a property in the prototype chain?

2011-04-11 Thread David Bruant
Le 11/04/2011 21:47, Brendan Eich a écrit :
> On Apr 11, 2011, at 6:36 PM, Allen Wirfs-Brock wrote:
>
>> Personally, I prefer Object.getOwnPropertyDescriptor as a property existence 
>> test because it doesn't have the reflection the meta-circularity concern.  I 
>> would write Dave's original function as: 
>>
>> function getDefiningObject(obj, key) {
>>   var obj={}.valueOf.call(obj);  // ToObject in case primitive value passed
>>   while (obj) {
>>  if (Object.getOwnPropertyDescriptor(obj,key)) return obj;
>>  obj =  Object.getPrototypeOf(obj);
>>   }
>>   throw new Error("key " + key + " not found");
>> }
> Then the only downside is the pd allocation. Any way to avoid that?
Could static analysis help out to detect that the object is not going to
be used and consequently avoid the allocation?

David
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Setting a property in the prototype chain?

2011-04-11 Thread Brendan Eich
On Apr 11, 2011, at 6:36 PM, Allen Wirfs-Brock wrote:

> Personally, I prefer Object.getOwnPropertyDescriptor as a property existence 
> test because it doesn't have the reflection the meta-circularity concern.  I 
> would write Dave's original function as: 
> 
> function getDefiningObject(obj, key) {
>   var obj={}.valueOf.call(obj);  // ToObject in case primitive value passed
>   while (obj) {
>  if (Object.getOwnPropertyDescriptor(obj,key)) return obj;
>  obj =  Object.getPrototypeOf(obj);
>   }
>   throw new Error("key " + key + " not found");
> }

Then the only downside is the pd allocation. Any way to avoid that?

/be
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Setting a property in the prototype chain?

2011-04-11 Thread Allen Wirfs-Brock
Personally, I prefer Object.getOwnPropertyDescriptor as a property existence 
test because it doesn't have the reflection the meta-circularity concern.  I 
would write Dave's original function as: 

function getDefiningObject(obj, key) {
   var obj={}.valueOf.call(obj);  // ToObject in case primitive value passed
   while (obj) {
  if (Object.getOwnPropertyDescriptor(obj,key)) return obj;
  obj =  Object.getPrototypeOf(obj);
   }
   throw new Error("key " + key + " not found");
}


___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Setting a property in the prototype chain?

2011-04-11 Thread Jorge
On 11/04/2011, at 05:14, Mark S. Miller wrote:
> 
> On Apr 10, 2011, at 22:18 , David Herman wrote:
> 
> > function getDefiningObject(obj, key) {
> >if (!(key in obj))
> >throw new Error("key " + key + " not found");
> >while (!obj.hasOwnProperty(key))
> 
> That should be
> 
>  while (!{}.hasOwnProperty.call(obj, key))
> 
> which works even if obj has an own property named 'hasOwnProperty'.

And also because that would work for null too, unlike (null).hasOwnProperty( 
key ) that would throw "TypeError: 'null' is not an object (evaluating 
'(null).hasOwnProperty')", and null is at the end of the prototype chain of all 
objects...

Here's another take on it:

function getDefiningObject (o, key) {
  do {
if ( {}.hasOwnProperty.call(o, key) ) break;
  } while ( o = Object.getPrototypeOf(o) );
  return o;
}

getDefiningObject([1,2], 'length')
[1, 2]
getDefiningObject([1,2], 'pop')
[]
getDefiningObject([1,2], 'valueOf')
Object
getDefiningObject([1,2], 'none')
null
-- 
Jorge.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Setting a property in the prototype chain?

2011-04-10 Thread Axel Rauschmayer
> Exactly what I was looking for. Thanks.
> 
> Not exactly...

True. But it's OK for me as a work-around.

> That should be
> 
>  while (!{}.hasOwnProperty.call(obj, key))
> 
> which works even if obj has an own property named 'hasOwnProperty'.


IIRC, {} creates a new instance for each invocation. Thus, a better solution 
would be
while (!Object.prototype.hasOwnProperty.call(obj, key))

But I usually prefer David’s more readable version and take the risk of a name 
clash.

-- 
Dr. Axel Rauschmayer

a...@rauschma.de
twitter.com/rauschma

home: rauschma.de
blog: 2ality.com



___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Setting a property in the prototype chain?

2011-04-10 Thread David Herman
I wondered if someone was going to make this point.

> That should be
> 
>  while (!{}.hasOwnProperty.call(obj, key))
> 
> which works even if obj has an own property named 'hasOwnProperty'.

Not if someone mutates Object.prototype.hasOwnProperty or 
Function.prototype.call. I don't think we need to polish a proof of concept.

Dave

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Setting a property in the prototype chain?

2011-04-10 Thread Mark S. Miller
On Sun, Apr 10, 2011 at 6:59 PM, Axel Rauschmayer  wrote:

> Exactly what I was looking for. Thanks.
>

Not exactly...



>
> On Apr 10, 2011, at 22:18 , David Herman wrote:
>
> > function getDefiningObject(obj, key) {
> >if (!(key in obj))
> >throw new Error("key " + key + " not found");
> >while (!obj.hasOwnProperty(key))
>

That should be

 while (!{}.hasOwnProperty.call(obj, key))

which works even if obj has an own property named 'hasOwnProperty'.



> >obj = Object.getPrototypeOf(obj);
> >return obj;
> > }
> >
> > On Apr 10, 2011, at 10:24 AM, Axel Rauschmayer wrote:
> >
> >> As far as I am aware, there is no way to change a property that isn’t at
> the beginning of the property chain, because the change will create a new
> property there.
> >>
> >> Are there plans to change this? It would be nice to have something akin
> to class methods (without accessing the prototype via some other, e.g.
> global, reference).
> >>
> >> --
> >> Dr. Axel Rauschmayer
> >>
> >> a...@rauschma.de
> >> twitter.com/rauschma
> >>
> >> home: rauschma.de
> >> blog: 2ality.com
> >>
> >>
> >>
> >> ___
> >> es-discuss mailing list
> >> es-discuss@mozilla.org
> >> https://mail.mozilla.org/listinfo/es-discuss
> >
> >
>
> --
> Dr. Axel Rauschmayer
>
> a...@rauschma.de
> twitter.com/rauschma
>
> home: rauschma.de
> blog: 2ality.com
>
>
>
> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>



-- 
Cheers,
--MarkM
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Setting a property in the prototype chain?

2011-04-10 Thread Axel Rauschmayer
>> As far as I am aware, there is no way to change a property that isn’t at the 
>> beginning of the property chain, because the change will create a new 
>> property there.
>> 
>> Are there plans to change this? It would be nice to have something akin to 
>> class methods (without accessing the prototype via some other, e.g. global, 
>> reference).

> In order to access a reference to the prototype of an object, you can use 
> Object.getPrototypeOf.

Right. That's what I didn’t think of: Iterating over the prototype chain until 
you get to the object that actually owns a given property and then set it there.

Thanks,

Axel

-- 
Dr. Axel Rauschmayer

a...@rauschma.de
twitter.com/rauschma

home: rauschma.de
blog: 2ality.com



___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Setting a property in the prototype chain?

2011-04-10 Thread Axel Rauschmayer
Exactly what I was looking for. Thanks.

On Apr 10, 2011, at 22:18 , David Herman wrote:

> function getDefiningObject(obj, key) {
>if (!(key in obj))
>throw new Error("key " + key + " not found");
>while (!obj.hasOwnProperty(key))
>obj = Object.getPrototypeOf(obj);
>return obj;
> }
> 
> On Apr 10, 2011, at 10:24 AM, Axel Rauschmayer wrote:
> 
>> As far as I am aware, there is no way to change a property that isn’t at the 
>> beginning of the property chain, because the change will create a new 
>> property there.
>> 
>> Are there plans to change this? It would be nice to have something akin to 
>> class methods (without accessing the prototype via some other, e.g. global, 
>> reference).
>> 
>> -- 
>> Dr. Axel Rauschmayer
>> 
>> a...@rauschma.de
>> twitter.com/rauschma
>> 
>> home: rauschma.de
>> blog: 2ality.com
>> 
>> 
>> 
>> ___
>> es-discuss mailing list
>> es-discuss@mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
> 
> 

-- 
Dr. Axel Rauschmayer

a...@rauschma.de
twitter.com/rauschma

home: rauschma.de
blog: 2ality.com



___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Setting a property in the prototype chain?

2011-04-10 Thread David Herman
function getDefiningObject(obj, key) {
if (!(key in obj))
throw new Error("key " + key + " not found");
while (!obj.hasOwnProperty(key))
obj = Object.getPrototypeOf(obj);
return obj;
}

On Apr 10, 2011, at 10:24 AM, Axel Rauschmayer wrote:

> As far as I am aware, there is no way to change a property that isn’t at the 
> beginning of the property chain, because the change will create a new 
> property there.
> 
> Are there plans to change this? It would be nice to have something akin to 
> class methods (without accessing the prototype via some other, e.g. global, 
> reference).
> 
> -- 
> Dr. Axel Rauschmayer
> 
> a...@rauschma.de
> twitter.com/rauschma
> 
> home: rauschma.de
> blog: 2ality.com
> 
> 
> 
> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Setting a property in the prototype chain?

2011-04-10 Thread David Bruant
Le 10/04/2011 19:24, Axel Rauschmayer a écrit :
> As far as I am aware, there is no way to change a property that isn’t at the 
> beginning of the property chain, because the change will create a new 
> property there.
>
> Are there plans to change this? It would be nice to have something akin to 
> class methods (without accessing the prototype via some other, e.g. global, 
> reference).
The ES5 Object.* API already provides everything you need to manipulate
all properties you can find in an object (own or inherited).
The "lowest-level" method to change the value of an own property is
Object.defineProperty. This method can also be used to "re-configure" a
property (make it non-configurable, change its enumerablity, change its
"type" (data/accessor), change its writability if it is described by a
data property descriptor). For examples, I recommend reading the MDN doc
[1].
In order to access a reference to the prototype of an object, you can
use Object.getPrototypeOf. Using both, you have enough power to achieve
any change you could think of on any property of an object (own or
inherited).
Few platforms implement both at the moment. See [2] for reference.
As Dmitry said, inherited accessor properties could be enough for what
you need.

David

[1]
https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/defineProperty
[2] http://kangax.github.com/es5-compat-table/
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Setting a property in the prototype chain?

2011-04-10 Thread Dmitry A. Soshnikov

On 10.04.2011 21:24, Axel Rauschmayer wrote:

As far as I am aware, there is no way to change a property that isn’t at the 
beginning of the property chain, because the change will create a new property 
there.

Are there plans to change this? It would be nice to have something akin to 
class methods (without accessing the prototype via some other, e.g. global, 
reference).



Inherited accessor property can be change normally via assignment. Also 
`Object.defineProperty` is a way.


Dmitry.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss