Inheriting Data Properties

Discussion in 'Javascript' started by Benjy Borda, Jul 4, 2009.

  1. Benjy Borda

    Benjy Borda Guest

    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?
     
    Benjy Borda, Jul 4, 2009
    #1
    1. Advertising

  2. Benjy Borda

    slebetman Guest

    On Jul 5, 5:18 am, 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.
    >
    > 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
    >


    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();
     
    slebetman, Jul 5, 2009
    #2
    1. Advertising

  3. Benjy Borda

    Benjy Borda Guest

    On Jul 4, 7:30 pm, slebetman <> wrote:
    > On Jul 5, 5:18 am, 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.

    >
    > > 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

    >
    > 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();


    Because then all WidgetA objects will share the same div from the
    prototype. Each object needs its own.
     
    Benjy Borda, Jul 5, 2009
    #3
  4. 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$>
     
    Thomas 'PointedEars' Lahn, Jul 5, 2009
    #4
  5. Benjy Borda

    slebetman Guest

    On Jul 5, 7:40 am, Benjy Borda <> wrote:
    > On Jul 4, 7:30 pm, slebetman <> wrote:
    >
    >
    >
    > > On Jul 5, 5:18 am, 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.

    >
    > > > 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

    >
    > > 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();

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


    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();
     
    slebetman, Jul 5, 2009
    #5
  6. Benjy Borda

    Benjy Borda Guest

    My apologies for the syntax errors but thanks for your help Thomas
    Lahn.

    On Jul 4, 8:28 pm, 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:
    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?)
     
    Benjy Borda, Jul 5, 2009
    #6
  7. kangax wrote:
    > Thomas 'PointedEars' Lahn wrote:
    >> Benjy Borda wrote:
    >>> 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/.

    >
    > 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
    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:>
    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, Jul 5, 2009
    #7
  8. 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:>.


    Regards,

    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$>
     
    Thomas 'PointedEars' Lahn, Jul 5, 2009
    #8
  9. 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
     
    John G Harris, Jul 5, 2009
    #9
  10. 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:>
    >> 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
    --
    var bugRiddenCrashPronePieceOfJunk = (
    navigator.userAgent.indexOf('MSIE 5') != -1
    && navigator.userAgent.indexOf('Mac') != -1
    ) // Plone, register_function.js:16
     
    Thomas 'PointedEars' Lahn, Jul 10, 2009
    #10
  11. 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>
     
    Thomas 'PointedEars' Lahn, Jul 12, 2009
    #11
  12. Benjy Borda

    RobG Guest

    On Jul 5, 12:08 pm, slebetman <> 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
     
    RobG, Jul 16, 2009
    #12
  13. 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
     
    Thomas 'PointedEars' Lahn, Jul 17, 2009
    #13
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Nathan Sokalski
    Replies:
    0
    Views:
    943
    Nathan Sokalski
    Oct 17, 2005
  2. =?Utf-8?B?Q2hyaXN0b3BoZSBQZWlsbGV0?=

    CompositeControls: ViewState properties w/ Mapped properties probl

    =?Utf-8?B?Q2hyaXN0b3BoZSBQZWlsbGV0?=, Jan 19, 2006, in forum: ASP .Net
    Replies:
    1
    Views:
    1,158
    Steven Cheng[MSFT]
    Jan 19, 2006
  3. Kent Lichty
    Replies:
    0
    Views:
    848
    Kent Lichty
    Apr 16, 2004
  4. Jay

    Inheriting style and properties

    Jay, Jul 26, 2004, in forum: ASP .Net Building Controls
    Replies:
    3
    Views:
    139
    John Saunders
    Jul 27, 2004
  5. Dann Pool
    Replies:
    0
    Views:
    120
    Dann Pool
    Nov 11, 2003
Loading...

Share This Page