Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Inheriting Data Properties

0 views
Skip to first unread message

Benjy Borda

unread,
Jul 4, 2009, 5:18:56 PM7/4/09
to
I assume this question must have been answered in the past, but I have
been searching the archives the last couple of days and cannot find a
solid answer to my problem.

I have a couple of properties that need to be created with every new
object created. To simplify, assume the only property I need to do
this with is called 'dom', which stores a dom object. In this context,
every object will need to create its own dom to avoid sharing of the
same dom object. A solution I have is like so:

var clone = (function(){
function F(){}
return (function(o){
F.prototype = o;
return new F();
});
})();

var proto_root = { /* bunch of methods */};

function Root() {
this.dom = document.createElement('div');
}
Root.prototype = proto_root;

var proto_widgetA = clone(proto_root);
var proto_widgetA.someNewProp = function() { //does something}

function WidgetA() {
Root.call(this); // to set the dom property
// set some specific "widgetA" properties
}
WidgetA.prototype = proto_widgetA;

Then create new widgetA like: var w = new WidgetA();

There will eventually be lots of widgetXYZ constructors and more
objects that inherit from those

This will WORK, but I can't help but feel like it is not the correct
way to accomplish such a thing in a prototype based language.
Inheriting properties like this makes me feel like I am coupling these
constructors too much together and gives me a feel of creating classes
in a class-based language.

An alternative I could come up with that "feels" more prototypical:
function addDom(o) {
o.dom = document.createElement('div');
return o;
}

var root = { /* bunch of methods */};

var proto_widgetA = clone(root);
var proto_widgetA.someNewProp = function() { //does something}

function widgetA() {
var w = addDom(clone(proto_widgetA)); // note the addDom call
here
// add widgetA stuff
return w;
}

and create widgetA's like: var w = widgetA();

The problem I see with this is that there may eventually end up with
things like:
addDom(addSomething(addSomethingElse(clone(obj)));
Which seems ugly to me

What are your thoughts on my two proposed methods? How would you solve
the same problem?

slebetman

unread,
Jul 4, 2009, 7:30:01 PM7/4/09
to

Eh? Why overcomplicate what you're trying to do? Why not do it the
native way:

// Root constructor:
function Root () {


this.dom = document.createElement('div');

this.method1 = function () {//...}
this.method2 = function () {//...}
}

// WidgetA constructor:
function WidgetA () {
// bunch of methods and attributes
}
// Inherit from Root:
WidgetA.prototype = new Root();

Benjy Borda

unread,
Jul 4, 2009, 7:40:01 PM7/4/09
to

Because then all WidgetA objects will share the same div from the
prototype. Each object needs its own.

Thomas 'PointedEars' Lahn

unread,
Jul 4, 2009, 8:28:46 PM7/4/09
to
Benjy Borda wrote:
> I assume this question must have been answered in the past, but I have
> been searching the archives the last couple of days and cannot find a
> solid answer to my problem.

One reason for that is that there is the rather junky Prototype.js library
which has frequently been referred to just as "Prototype"; however,
"prototype chain" should prove to be enlightening. I, for one, remember to
have submitted a number of postings on the subject here that use this term.

> I have a couple of properties that need to be created with every new
> object created. To simplify, assume the only property I need to do
> this with is called 'dom', which stores a dom object. In this context,
> every object will need to create its own dom to avoid sharing of the
> same dom object. A solution I have is like so:
>
> var clone = (function(){
> function F(){}
> return (function(o){

^


> F.prototype = o;
> return new F();
> });

^
`function() { ... }' is a proper expression (see below). You need the
additional parentheses only if the /FunctionExpression/ is part of a
/CallExpression/.

> })();

If you do this, `F' is a bound variable in the returned function (as
understood in closures), meaning that all objects you create with clone()
are "F objects" and thus share the same prototype chain. You really don't
want that. Using closures to increase efficiency is usually commendable but
counterproductive here.

> var proto_root = { /* bunch of methods */};

You don't need or want this variable.

> function Root() {

Shouldn't that be a more talking identifier, like ` DivWrapper'?

> this.dom = document.createElement('div');
> }
> Root.prototype = proto_root;

You can (and should) assign the object reference directly.

Root.prototype = {
// ...
};

However, see below for the drawbacks of this approach.

> var proto_widgetA = clone(proto_root);
> var proto_widgetA.someNewProp = function() { //does something}

^[1] ^^^^^^^^^^^^^^^^^[2]
There are two syntax errors.

[1] A variable name must be an /Identifier/, and an /Identifier/ MUST NOT
contain dots (or other non-word characters except for escape sequences).

[2] The single-line comment disables the `}' so this does not match
/FunctionExpression/.

Did you mean

proto_widgetA.someNewProp = function() { /* does something */ };

?

> function WidgetA() {
> Root.call(this); // to set the dom property
> // set some specific "widgetA" properties
> }
> WidgetA.prototype = proto_widgetA;

Note that if you do this you overwrite the default prototype object which
includes the `constructor' property. There are two possibilities to work
around that: redefine the `constructor' property in your prototype object
(here referred to by proto_widgetA, but the variable is unnecessary), or
only add/overwrite properties in a loop.

> Then create new widgetA like: var w = new WidgetA();
>
> There will eventually be lots of widgetXYZ constructors and more
> objects that inherit from those

All the more reason to set up different prototype chains.

> This will WORK, but I can't help but feel like it is not the correct
> way to accomplish such a thing in a prototype based language.

Your bad feeling ist justified. You are on the right track (IMHO), but have
a few steps to go.

> [...]


> The problem I see with this is that there may eventually end up with
> things like:
> addDom(addSomething(addSomethingElse(clone(obj)));
> Which seems ugly to me

It is.

> What are your thoughts on my two proposed methods? How would you solve
> the same problem?

With the exception of the syntax errors in your code, I'm using more or less
the first variant (prototype properties are added to the prototype object of
the constructor instead, where they belong; the prototype object of the
constructor's prototype only serves for building the proper prototype chain).

It has frequently been recommended here, and I have not encountered any
problems with it so far; in fact, it has helped me greatly to set up an
exception hierarchy despite that Error usually cannot be reused. I'm using
less variables, though. Search for "inheritFrom" here for the basic
implementation.


PointedEars
--
Prototype.js was written by people who don't know javascript for people
who don't know javascript. People who don't know javascript are not
the best source of advice on designing systems that use javascript.
-- Richard Cornford, cljs, <f806at$ail$1$8300...@news.demon.co.uk>

slebetman

unread,
Jul 4, 2009, 10:08:49 PM7/4/09
to

Oh, forgot about that. I personally prefer to use the factory pattern
rather than constructors to create objects. It has a neater syntax and
does exactly what you want. The down side is that instanceof doesn't
work:

function makeRoot () {
this = {}


this.dom = document.createElement('div');
}

function makeWidgetA () {
this = makeRoot();
}

var a = makeWidgetA();

Benjy Borda

unread,
Jul 4, 2009, 10:24:22 PM7/4/09
to
My apologies for the syntax errors but thanks for your help Thomas
Lahn.

On Jul 4, 8:28 pm, Thomas 'PointedEars' Lahn <PointedE...@web.de>
wrote:


> If you do this, `F' is a bound variable in the returned function (as
> understood in closures), meaning that all objects you create with clone()
> are "F objects" and thus share the same prototype chain.  You really don't
> want that.  Using closures to increase efficiency is usually commendable but
> counterproductive here.

This got me thinking because that is what I thought was going to
happen when I read this code. However, this is not the results I am
seeing:


var clone = (function(){
function F(){}

return function(o){


F.prototype = o;
return new F();

};
})();

// Some random objects to be cloned
var proto1 = {prop1: 'prop1'};
var proto2 = {prop2: 'prop2'};

function x() {}
x.prototype = clone(proto1);

function y() {}
y.prototype = clone(proto2);

var x1 = new x();
var y1 = new y();

Now I get the following values:
x1.prop1 => 'prop1'
x1.prop2 => undefined
y1.prop1 => undefined
y1.prop2 => 'prop2'

My expectations were that the initial call to clone would setup the
prototype hierarchy as:
new F() (an empty object) => proto1 => ...
and then the second call to clone would replace proto1 in the above
chain with proto2. And since F objects share the same prototype, all
new x and y objects should only inherit properties from proto2. I
would have expected to see x1.prop1 => undefined and x1.prop2 =>
'prop2'.

Clearly, something is going on here that does not make sense to me
(perhaps related to __proto__ property on new F objects?)

kangax

unread,
Jul 4, 2009, 11:44:29 PM7/4/09
to

Where did you get that from?

CallExpression:
MemberExpression Arguments

MemberExpression:
FunctionExpression

FunctionExpression:
function Identifier opt ( FormalParameterListopt ){ FunctionBody }

Arguments:
()

`function(){}()` (i.e. /FunctionExpression/ as part of /CallExpression/)
looks perfectly valid to me. I don't see why one would need additional
parenthesis here, except for clarity/convention.

>
>> })();
>
> If you do this, `F' is a bound variable in the returned function (as
> understood in closures), meaning that all objects you create with clone()
> are "F objects" and thus share the same prototype chain. You really don't
> want that. Using closures to increase efficiency is usually commendable but
> counterproductive here.

I'm failing to see how prototype chain is shared here. If `F.prototype`
is being assigned a new object on `clone` invocation, and returned
object is then initialized with [[Prototype]] referencing this new `o`
object, what does it matter that the same function object was used as
constructor?

[...]

--
kangax

Thomas 'PointedEars' Lahn

unread,
Jul 5, 2009, 4:22:48 AM7/5/09
to

Parantheses are not needed when the CallExpression is produced only through
AssignmentExpression, but they are needed when CallExpression is produced
through ExpressionStatement.

function/* ... */(/* ... */){/* ... */}(/* ... */);

won't compile, because of:

| Statement :
| [...]
| ExpressionStatement

| ExpressionStatement :
| [lookahead ∉ {{, function}] Expression ;

I have since made it my code convention to parenthesize called
FunctionExpressions always. Sorry for the oversimplification.

>> If you do this, `F' is a bound variable in the returned function (as
>> understood in closures), meaning that all objects you create with clone()
>> are "F objects" and thus share the same prototype chain. You really don't
>> want that. Using closures to increase efficiency is usually commendable but
>> counterproductive here.
>
> I'm failing to see how prototype chain is shared here. If `F.prototype`
> is being assigned a new object on `clone` invocation, and returned
> object is then initialized with [[Prototype]] referencing this new `o`
> object, what does it matter that the same function object was used as
> constructor?

I had planned a figure for my refutation, but in making it I saw all too
quickly that I had been wrong, and that it doesn't really matter -- as you
indicated -- that the constructor is the same. (Which is supported by
Benjy's observations.)

Because the prototype chain of an object is not defined indirectly through
the instance-constructor-prototype relationship but directly through the
internal [[Prototype]] property which is set on creation of the object.

Maybe I will modify my inheritance method accordingly.

For the figure, I have used the property names from the OP's
<news:fd42b071-d246-476b...@b14g2000yqd.googlegroups.com>
to indicate object indentity.

I have tried to stay as less confusing as possible. Arrows with "solid"
lines indicate normal object references, while arrows with "dotted" lines
indicate the prototype chain (which boils down to object references as well
but cannot be modified in a standards-compliant way; see below).

I hope it makes any sense (fixed-width font required, of course):

,--[Function object "F"]--.
| | .--> 1. [Object object "o_1"] <--.
| prototype -----------------' :
| ... | '--> 2. [Object object "o_2"] <- - -.
`-------------------------' : :
^ ^ : :
| | ,--[Object object "proto1"]--. : :
| | | | : :
| '--- constructor | : :
| | [[Prototype]] - - - - - - - - - - - - - - - - - - --' :
| | ... | :
| `----------------------------' :
| ^ ^ :
| | '- - - - - - - - - --. :
| | : :
| '-------------------. : :
| | : :
| ,--[Object object "proto2"]--. | : :
| | | | : :
'------- constructor | | : :
| [[Prototype]] - - - - - - - - - - - - - - - - - - - --'
| ... | | :
`----------------------------' | :
^ ^ | :
| '- - - - - - - - - - - - - - - - - - - --.
| | : :
'----------------------------------. :
| : | :
| : | :
,--[Function object "x"]-----. | : | :
| | | : | :
| prototype --------------------' : | :
| ... | : | :
`----------------------------' : | :
^ : | :
.----------------' : | :
| : | :
1. | ,--[Object object "x1"]------. : | :
| | | : | :
'--- constructor | : | :
| [[Prototype]] - - - - - - - - - - -' | :
| ... | | :
`----------------------------' | :
| :
,--[Function object "y"]-----. | :
| | | :
| prototype ------------------------------------' :
| ... | :
`----------------------------' :
^ :
.----------------' :
| :
2. | ,--[Object object "x2"]------. :
| | | :
'--- constructor | :
| [[Prototype]] - - - - - - - - - - - - - - - - - - - - --'
| ... |
`----------------------------'

Benjy: The proprietary `__proto__' property of JavaScript™ objects allows
direct access to the internal [[Prototype]] property. Objects in other
ECMAScript implementations don't have it.¹


PointedEars
___________
¹ Confirmed for JScript (in IE/MSHTML), Opera ECMAScript,
and KJS (in KHTML and WebKit).
--
var bugRiddenCrashPronePieceOfJunk = (
navigator.userAgent.indexOf('MSIE 5') != -1
&& navigator.userAgent.indexOf('Mac') != -1
) // Plone, register_function.js:16

Thomas 'PointedEars' Lahn

unread,
Jul 5, 2009, 4:30:22 AM7/5/09
to
Benjy Borda wrote:
> My apologies for the syntax errors but thanks for your help Thomas
> Lahn.

You are welcome. And call me Thomas or PointedEars (in references you may
use "PE", appears to have been widely adopted).

> Thomas 'PointedEars' Lahn wrote:
>> If you do this, `F' is a bound variable in the returned function (as
>> understood in closures), meaning that all objects you create with clone()
>> are "F objects" and thus share the same prototype chain. You really don't
>> want that. Using closures to increase efficiency is usually commendable but
>> counterproductive here.
>
> This got me thinking because that is what I thought was going to
> happen when I read this code. However, this is not the results I am

> seeing: [...]

I was wrong, see <news:4A5062D8...@PointedEars.de>.


Regards,

John G Harris

unread,
Jul 5, 2009, 11:34:31 AM7/5/09
to
On Sun, 5 Jul 2009 at 02:28:46, in comp.lang.javascript, Thomas
'PointedEars' Lahn wrote:

<snip>


>Note that if you do this you overwrite the default prototype object which
>includes the `constructor' property. There are two possibilities to work
>around that: redefine the `constructor' property in your prototype object
>(here referred to by proto_widgetA, but the variable is unnecessary), or
>only add/overwrite properties in a loop.

<snip>

Or notice that the 'constructor' property isn't used and don't bother
creating it.

Elsewhere, if objects are created by beget, aka create, aka clone, there
isn't a sensible constructor function to point to.

John
--
John Harris

kangax

unread,
Jul 10, 2009, 12:42:53 PM7/10/09
to
Thomas 'PointedEars' Lahn wrote:
> kangax wrote:
>> Thomas 'PointedEars' Lahn wrote:

[..]

>>> `function() { ... }' is a proper expression (see below). You need the
>>> additional parentheses only if the /FunctionExpression/ is part of a
>>> /CallExpression/.
>> Where did you get that from?
>>
>> CallExpression:
>> MemberExpression Arguments
>>
>> MemberExpression:
>> FunctionExpression
>>
>> FunctionExpression:
>> function Identifier opt ( FormalParameterListopt ){ FunctionBody }
>>
>> Arguments:
>> ()
>>
>> `function(){}()` (i.e. /FunctionExpression/ as part of /CallExpression/)
>> looks perfectly valid to me. I don't see why one would need additional
>> parenthesis here, except for clarity/convention.
>
> Parantheses are not needed when the CallExpression is produced only through
> AssignmentExpression, but they are needed when CallExpression is produced

Only through /AssignmentExpression/? What about these cases? I don't see
/AssignmentExpression/'s here:


(function(){
...
return function(){}();
^^^^^^^^^^^^^^
...
})();

typeof function(){}();
^^^^^^^^^^^^^^

> through ExpressionStatement.
>
> function/* ... */(/* ... */){/* ... */}(/* ... */);
>
> won't compile, because of:
>
> | Statement :
> | [...]
> | ExpressionStatement
>
> | ExpressionStatement :
> | [lookahead ∉ {{, function}] Expression ;
>
> I have since made it my code convention to parenthesize called
> FunctionExpressions always. Sorry for the oversimplification.

ACK. I find such convention very useful myself.

>
>>> If you do this, `F' is a bound variable in the returned function (as
>>> understood in closures), meaning that all objects you create with clone()
>>> are "F objects" and thus share the same prototype chain. You really don't
>>> want that. Using closures to increase efficiency is usually commendable but
>>> counterproductive here.
>> I'm failing to see how prototype chain is shared here. If `F.prototype`
>> is being assigned a new object on `clone` invocation, and returned
>> object is then initialized with [[Prototype]] referencing this new `o`
>> object, what does it matter that the same function object was used as
>> constructor?
>
> I had planned a figure for my refutation, but in making it I saw all too
> quickly that I had been wrong, and that it doesn't really matter -- as you
> indicated -- that the constructor is the same. (Which is supported by
> Benjy's observations.)
>
> Because the prototype chain of an object is not defined indirectly through
> the instance-constructor-prototype relationship but directly through the
> internal [[Prototype]] property which is set on creation of the object.

Yes. I think an important point here (which can be easily seen in your
diagram) is that while objects "proto1" and "proto2" reference same "F"
constructor, their [[Prototype]]'s reference distinct objects (produced
through that single constructor).

>
> Maybe I will modify my inheritance method accordingly.

I am surprised to hear you're not reusing "dummy" function in
"clone"/"inherit"/"beget", as explained and recommended by Cornford as
far back as few years ago (don't have link to his post at the moment).

>
> For the figure, I have used the property names from the OP's
> <news:fd42b071-d246-476b...@b14g2000yqd.googlegroups.com>
> to indicate object indentity.
>
> I have tried to stay as less confusing as possible. Arrows with "solid"
> lines indicate normal object references, while arrows with "dotted" lines
> indicate the prototype chain (which boils down to object references as well
> but cannot be modified in a standards-compliant way; see below).
>
> I hope it makes any sense (fixed-width font required, of course):

Yep. Makes perfect sense after careful observation.

WebKit-based environments have had `__proto__` for a while now.
Blackberry's proprietary implementation had it too, las time I checked
(not sure if they are using webkit).

Also, FF3.5 has (soon-to-be-standard) ES5's `Object.getPrototypeOf`,
probably as a replacement for proprietary `__proto__`.

--
kangax

Thomas 'PointedEars' Lahn

unread,
Jul 10, 2009, 2:38:14 PM7/10/09
to
kangax wrote:
> Thomas 'PointedEars' Lahn wrote:
>> kangax wrote:
>>> Thomas 'PointedEars' Lahn wrote:
>>>> `function() { ... }' is a proper expression (see below). You need the
>>>> additional parentheses only if the /FunctionExpression/ is part of a
>>>> /CallExpression/.
>>> Where did you get that from?
>>>
>>> CallExpression:
>>> MemberExpression Arguments
>>>
>>> MemberExpression:
>>> FunctionExpression
>>>
>>> FunctionExpression:
>>> function Identifier opt ( FormalParameterListopt ){ FunctionBody }
>>>
>>> Arguments:
>>> ()
>>>
>>> `function(){}()` (i.e. /FunctionExpression/ as part of /CallExpression/)
>>> looks perfectly valid to me. I don't see why one would need additional
>>> parenthesis here, except for clarity/convention.
>> Parantheses are not needed when the CallExpression is produced only through
^^^^^^^^^^^

>> AssignmentExpression, but they are needed when CallExpression is produced
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

> Only through /AssignmentExpression/? What about these cases? I don't see
> /AssignmentExpression/'s here:
>
>
> (function(){
> ...
> return function(){}();
> ^^^^^^^^^^^^^^
> ...
> })();
>
> typeof function(){}();
> ^^^^^^^^^^^^^^

Those are ExpressionStatements.

>> through ExpressionStatement.
^^^^^^^^^^^^^^^^^^^^^^^^^^^

>> [...] the prototype chain of an object is not defined indirectly through


>> the instance-constructor-prototype relationship but directly through the
>> internal [[Prototype]] property which is set on creation of the object.

> [...]


>> Maybe I will modify my inheritance method accordingly.
>
> I am surprised to hear you're not reusing "dummy" function in
> "clone"/"inherit"/"beget", as explained and recommended by Cornford as
> far back as few years ago (don't have link to his post at the moment).

Probably I overlooked it then, too.

>> For the figure, I have used the property names from the OP's
>> <news:fd42b071-d246-476b...@b14g2000yqd.googlegroups.com>
>> to indicate object indentity.
>>
>> I have tried to stay as less confusing as possible. Arrows with "solid"
>> lines indicate normal object references, while arrows with "dotted" lines
>> indicate the prototype chain (which boils down to object references as well
>> but cannot be modified in a standards-compliant way; see below).
>>
>> I hope it makes any sense (fixed-width font required, of course):
>
> Yep. Makes perfect sense after careful observation.

Thanks, but you wouldn't have needed to quote it in full (although it
demonstrates that it can even be quoted :))

>> [...]


>> Benjy: The proprietary `__proto__' property of JavaScript™ objects allows
>> direct access to the internal [[Prototype]] property. Objects in other
>> ECMAScript implementations don't have it.¹
>
> WebKit-based environments have had `__proto__` for a while now.

Unfortunately, Safari doesn't run "at home" (where I wrote that article).
Something in it is incompatible with WINE or vice-versa. Hence the footnote.

> Blackberry's proprietary implementation had it too, las time I checked
> (not sure if they are using webkit).

However, your statement is not supported by the documentation¹.

If there was another ECMAScript implementation to consider, that would be
rather important for me to know at this point. As I have not access to a
BlackBerry, and the documentation¹ doesn't appear to help here², could you
please provide the value of navigator.userAgent or other information which
might provide some insight as to that?

¹ <http://na.blackberry.com/eng/deliverables/8861/Overview_790346_11.jsp>
² However, it lead me to use mozplugger after all. Works like a charm :)

> Also, FF3.5 has (soon-to-be-standard)
^^^^^^^^^^^^^^^^^^^^^
We'll see. So far it is only a *working draft*.

> ES5's `Object.getPrototypeOf`, probably as a replacement for proprietary
> `__proto__`.

Good to know, thanks. One wonders, though, when ES 5 would draw
considerable attention by other vendors so that this would become
a really useful fact.


PointedEars

kangax

unread,
Jul 10, 2009, 3:10:32 PM7/10/09
to
Thomas 'PointedEars' Lahn wrote:
> kangax wrote:
>> Thomas 'PointedEars' Lahn wrote:
>>> kangax wrote:
[...]

>>>> `function(){}()` (i.e. /FunctionExpression/ as part of /CallExpression/)
>>>> looks perfectly valid to me. I don't see why one would need additional
>>>> parenthesis here, except for clarity/convention.
>>> Parantheses are not needed when the CallExpression is produced only through
> ^^^^^^^^^^^
>>> AssignmentExpression, but they are needed when CallExpression is produced
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>> Only through /AssignmentExpression/? What about these cases? I don't see
>> /AssignmentExpression/'s here:
>>
>>
>> (function(){
>> ...
>> return function(){}();
>> ^^^^^^^^^^^^^^
^ ^

>> ...
>> })();
>>
>> typeof function(){}();
>> ^^^^^^^^^^^^^^
^ ^

>
> Those are ExpressionStatements.

Exactly :) Yet, parenthesis are not needed. You said they are, and even
underlined your exact phrasing afterwards. Which one of us is going crazy?

[...]

>>> [...]
>>> Benjy: The proprietary `__proto__' property of JavaScript™ objects allows
>>> direct access to the internal [[Prototype]] property. Objects in other
>>> ECMAScript implementations don't have it.¹
>> WebKit-based environments have had `__proto__` for a while now.
>
> Unfortunately, Safari doesn't run "at home" (where I wrote that article).
> Something in it is incompatible with WINE or vice-versa. Hence the footnote.

Have you tried installing Chromium on Linux? I've heard they had
significant progress in that "field".

>
>> Blackberry's proprietary implementation had it too, las time I checked
>> (not sure if they are using webkit).
>
> However, your statement is not supported by the documentation¹.
>
> If there was another ECMAScript implementation to consider, that would be
> rather important for me to know at this point. As I have not access to a
> BlackBerry, and the documentation¹ doesn't appear to help here², could you
> please provide the value of navigator.userAgent or other information which
> might provide some insight as to that?

"BlackBerry9500/4.7.0.41 Profile/MIDP-2.0 Configuration/CLDC-1.1
VendorID/-1"

And yes, `__proto__` exists there, although I haven't checked if it's
functional.

>
> ¹ <http://na.blackberry.com/eng/deliverables/8861/Overview_790346_11.jsp>
> ² However, it lead me to use mozplugger after all. Works like a charm :)
>
>> Also, FF3.5 has (soon-to-be-standard)
> ^^^^^^^^^^^^^^^^^^^^^
> We'll see. So far it is only a *working draft*.

Indeed.

>
>> ES5's `Object.getPrototypeOf`, probably as a replacement for proprietary
>> `__proto__`.
>
> Good to know, thanks. One wonders, though, when ES 5 would draw
> considerable attention by other vendors so that this would become
> a really useful fact.

IE8 is another browser that implemented parts of ES5.
`Object.defineProperty` and `JSON.stringify/parse` come to mind. Note
that FF3.5 and currently beta Chrome 3 also implement
`JSON.stringify/parse`.


--
kangax

Thomas 'PointedEars' Lahn

unread,
Jul 12, 2009, 5:53:40 PM7/12/09
to
kangax wrote:
> Thomas 'PointedEars' Lahn wrote:
>> kangax wrote:
>>> Thomas 'PointedEars' Lahn wrote:
>>>> kangax wrote:
>>>> [...]
>>>> Benjy: The proprietary `__proto__' property of JavaScript™ objects allows
>>>> direct access to the internal [[Prototype]] property. Objects in other
>>>> ECMAScript implementations don't have it.¹
>>> WebKit-based environments have had `__proto__` for a while now.
>> Unfortunately, Safari doesn't run "at home" (where I wrote that article).
>> Something in it is incompatible with WINE or vice-versa. Hence the footnote.

JFYI: Finally, I got Safari 4 working on WINE with `winetricks' as described
on <http://alicious.com/2009/safari-4-on-linux-with-wine-update/>

(AFAICS, one of iphlpapi.dll, core fonts, and Flash Player plugin was missing.)

That is, the layout and script engines are working, so the Matrix's test
cases can run. Too bad that neither `javascript:' in the Location Bar (or
whatever Apple calls it) nor the Web Inspector/Error Console are usable, though.

> Have you tried installing Chromium on Linux? I've heard they had
> significant progress in that "field".

$ aptitude show chromium | grep ^Description:
Description: fast paced, arcade-style, scrolling space shooter

But I'm going to evaluate <http://code.google.com/chromium/>, too ;-)

>>> Blackberry's proprietary implementation had it too, las time I checked
>>> (not sure if they are using webkit).
>> However, your statement is not supported by the documentation¹.
>>
>> If there was another ECMAScript implementation to consider, that would be
>> rather important for me to know at this point. As I have not access to a
>> BlackBerry, and the documentation¹ doesn't appear to help here², could you
>> please provide the value of navigator.userAgent or other information which
>> might provide some insight as to that?
>
> "BlackBerry9500/4.7.0.41 Profile/MIDP-2.0 Configuration/CLDC-1.1
> VendorID/-1"

Hmmm, doesn't look like WebKit. Apparently there is a another /doc I have
to dig through.

> And yes, `__proto__` exists there, although I haven't checked if it's
> functional.

Please do and report back here.

>>> ES5's `Object.getPrototypeOf`, probably as a replacement for proprietary
>>> `__proto__`.
>> Good to know, thanks. One wonders, though, when ES 5 would draw
>> considerable attention by other vendors so that this would become
>> a really useful fact.
>
> IE8 is another browser that implemented parts of ES5.
> `Object.defineProperty` and `JSON.stringify/parse` come to mind. Note
> that FF3.5 and currently beta Chrome 3 also implement
> `JSON.stringify/parse`.

The Matrix has you.

JFTR: I'm going to look into the ES grammar issue later.


PointedEars
--
Use any version of Microsoft Frontpage to create your site.
(This won't prevent people from viewing your source, but no one
will want to steal it.)
-- from <http://www.vortex-webdesign.com/help/hidesource.htm>

kangax

unread,
Jul 15, 2009, 11:32:20 PM7/15/09
to
Thomas 'PointedEars' Lahn wrote:
> kangax wrote:
[...]
>> Have you tried installing Chromium on Linux? I've heard they had
>> significant progress in that "field".
>
> $ aptitude show chromium | grep ^Description:
> Description: fast paced, arcade-style, scrolling space shooter

lol

>
> But I'm going to evaluate <http://code.google.com/chromium/>, too ;-)
>
>>>> Blackberry's proprietary implementation had it too, las time I checked
>>>> (not sure if they are using webkit).
>>> However, your statement is not supported by the documentation¹.
>>>
>>> If there was another ECMAScript implementation to consider, that would be
>>> rather important for me to know at this point. As I have not access to a
>>> BlackBerry, and the documentation¹ doesn't appear to help here², could you
>>> please provide the value of navigator.userAgent or other information which
>>> might provide some insight as to that?
>> "BlackBerry9500/4.7.0.41 Profile/MIDP-2.0 Configuration/CLDC-1.1
>> VendorID/-1"
>
> Hmmm, doesn't look like WebKit. Apparently there is a another /doc I have
> to dig through.

Do you know of some other way to check engine being used? I remember
something about webkit returning "//" for `new RegExp('').toString()`,
while all (?) other browsers would result in - "(?:)".

Blackberry returns former one, which is why I thought it is based on webkit.

>
>> And yes, `__proto__` exists there, although I haven't checked if it's
>> functional.
>
> Please do and report back here.

Amazingly, __proto__ is readable, writable and even restorable (contrary
to FF, IIRC)

Object.prototype == ({}).__proto__; // true
Array.prototype == ([]).__proto__; // true

var o = { };
o.__proto__ = null;
o.__proto__; // null

o.toString; // undefined

o.__proto__ = Object.prototype;
o.toString === Object.prototype.toString; // true

>
>>>> ES5's `Object.getPrototypeOf`, probably as a replacement for proprietary
>>>> `__proto__`.
>>> Good to know, thanks. One wonders, though, when ES 5 would draw
>>> considerable attention by other vendors so that this would become
>>> a really useful fact.
>> IE8 is another browser that implemented parts of ES5.
>> `Object.defineProperty` and `JSON.stringify/parse` come to mind. Note
>> that FF3.5 and currently beta Chrome 3 also implement
>> `JSON.stringify/parse`.
>
> The Matrix has you.
>
> JFTR: I'm going to look into the ES grammar issue later.

All right.

--
kangax

RobG

unread,
Jul 16, 2009, 1:52:21 AM7/16/09
to
On Jul 5, 12:08 pm, slebetman <slebet...@gmail.com> wrote:
[...]

> Oh, forgot about that. I personally prefer to use the factory pattern
> rather than constructors to create objects. It has a neater syntax and
> does exactly what you want. The down side is that instanceof doesn't
> work:
>
> function makeRoot () {
> this = {}

ECMA-262 Sect. 10.1.7
"...The this value associated with an execution
context is immutable."

You can't assign a value to the this keyword, the above code is never
executed.

> this.dom = document.createElement('div');
> }
>
> function makeWidgetA () {
> this = makeRoot();

If you could assign to the this keyword, its value would be undefined
since makeRoot has no return statement.

> }
>
> var a = makeWidgetA();

As above. If this statement was actually evaluated, a would be
undefined.


--
Rob

Thomas 'PointedEars' Lahn

unread,
Jul 16, 2009, 10:08:28 PM7/16/09
to
kangax wrote:
> Thomas 'PointedEars' Lahn wrote:
>> kangax wrote:
>>>> If there was another ECMAScript implementation to consider, that would be
>>>> rather important for me to know at this point. As I have not access to a
>>>> BlackBerry, and the documentation¹ doesn't appear to help here², could you
>>>> please provide the value of navigator.userAgent or other information which
>>>> might provide some insight as to that?
>>> "BlackBerry9500/4.7.0.41 Profile/MIDP-2.0 Configuration/CLDC-1.1
>>> VendorID/-1"
>> Hmmm, doesn't look like WebKit. Apparently there is a another /doc I have
>> to dig through.
>
> Do you know of some other way to check engine being used?

At this point (without nearly complete ES Matrix, without RTSL) none that
would not be based on weak inference.

> I remember something about webkit returning "//" for `new RegExp('').toString()`,
> while all (?) other browsers would result in - "(?:)".
>
> Blackberry returns former one, which is why I thought it is based on webkit.

That's what I mean.

>>> And yes, `__proto__` exists there, although I haven't checked if it's
>>> functional.
>> Please do and report back here.
>
> Amazingly, __proto__ is readable, writable and even restorable (contrary
> to FF, IIRC)

Thanks. And you are somewhat right, after `__proto__ = null' the property
cannot be restored; other first assignments keep it working, though.
(Firebug 1.4X.0b8 in Iceweasel 3.5 [JavaScript 1.8.1 TraceMonkey] shows
"true, true, undefined, undefined, false" for your test code.)


PointedEars
--
Anyone who slaps a 'this page is best viewed with Browser X' label on
a Web page appears to be yearning for the bad old days, before the Web,
when you had very little chance of reading a document written on another
computer, another word processor, or another network. -- Tim Berners-Lee

0 new messages