Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.javascript > #29709

Re: Refer object within itself

From Thomas 'PointedEars' Lahn <PointedEars@web.de>
Newsgroups comp.lang.javascript
Subject Re: Refer object within itself
Date 2016-02-26 19:23 +0100
Organization PointedEars Software (PES)
Message-ID <10425603.zxHOPjekVl@PointedEars.de> (permalink)
References <76ydnVazm-uPoU3LnZ2dnUU7-TGdnZ2d@westnet.com.au>

Show all headers | View raw


Andrew Poulos wrote:

> Say I have this object
> 
> var foo {
         ^
>    "name":"bar"
>    "width":600
> }
> 
> and I want to add another element that references a value within the
> object itself. eg
> 
> var foo {
         ^
>    "name":"bar"
>    "width":600,
>    "height": width * 2
> }
> 
> Both
>    "height": this.width * 2
> and
>    "height": foo.width * 2
> 
> return errors or undefined.

They do because “width” has to be resolved *before* the object is 
constructed and a reference to it is assigned to “foo” (had you used the 
assignment operator).  Keep in mind that the above (if written correctly)
is functionally equivalent to:

  var o = new Object();
  o.name = "bar";
  o.width = 600;

  /* or this.width or foo.width, respectively */
  o.height = width * 2;

  foo = o;

> How do I reference to the object itself within the object?

The reason that your approach does not work is that you are _not_ “within 
the object” there.

> Or should it be done line this
> 
> var foo {
         ^
>    "name":"bar"
>    "width":600
> }
> foo.height = foo.width * 2;

Certainly not, as that would be a syntax error as well ;-)

You can write it thus:

  var foo = (function () { 
    var width = 600;

    return {
      name: "bar"
      width: width,
      height: width * 2
    };
  }());

That is not necessarily what you want, because the value of the “height” 
property is then not *bound* to the value of the “width” property of the 
same object: if the “width” property value changes, the “height” property 
value does not change with it.
  
Without Proxy (ECMAScript 2015+) – see Stefan Ram’s answer –, you can define 
this relationship in a more compatible way using a getter (ECMAScript Ed. 
5+):

  var foo = Object.create(Object.prototype, {
    name: {
      value: "bar",
      configurable: true,
      enumerable: true,
      writable: true
    },
    width: {
      value: 600,
      configurable: true,
      enumerable: true,
      writable: true
    },
    height: {
      "get": function () {
        return this.width * 2;
      },
      configurable: true,
      enumerable: true
    }
  }); 

or, less explicit:

  var foo = Object.defineProperty(
    {
      name: "bar",
      width: 600 
    },
    "height",
    {
      "get": function () { return this.width * 2; },
      configurable: true,
      enumerable: true
    }
  ); 

(Getters and Setters have been supported in various ways even before 
ECMAScript Ed. 5; see JSX:object.js for a wrapper implementation.)

You can use “null” instead of “Object.prototype” if you do not want your 
object to inherit any properties, and you can omit definitions for the 
“configurable”, “enumerable”, and “writable” properties if you want the 
property to be not configurable, enumerable, or writable, respectively.

Note that such an accessor property with only a getter is read-only, until 
you reconfigure it (which is only possible if it is also configurable) to 
have a setter (in which case the new getter needs to return, and the new 
setter needs to write a value of another property or variable), or to have a 
value instead (in which case it also should be defined as writable).

Therefore, another alternative is

  var foo = (function () {
    var width = 600;

    return Object.defineProperties({name: "bar"}, {
      width: {
        "get": function () { return width; },
        "set": function (value) { width = value; },
        configurable: true,
        enumerable: true
      },
      height: {
        "get": function () { return width * 2; },
        configurable: true,
        enumerable: true
      }
    });
  }());

-- 
PointedEars
FAQ: <http://PointedEars.de/faq> | SVN: <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-matrix>
Please do not cc me. / Bitte keine Kopien per E-Mail.

Back to comp.lang.javascript | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

Refer object within itself Andrew Poulos <ap_prog@hotmail.com> - 2016-02-26 22:50 +1100
  Re: Refer object within itself Scott Sauyet <scott.sauyet@gmail.com> - 2016-02-26 04:51 -0800
    Re: Refer object within itself "Evertjan." <exxjxw.hannivoort@inter.nl.net> - 2016-02-26 14:15 +0100
  Re: Refer object within itself "Christoph M. Becker" <cmbecker69@arcor.de> - 2016-02-26 16:43 +0100
    Re: Refer object within itself Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2016-02-26 19:25 +0100
  Re: Refer object within itself Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2016-02-26 19:23 +0100
  Refer object within itself Ram Tobolski <ramtob@gmail.com> - 2016-02-28 10:06 -0800
    Re: Refer object within itself "Evertjan." <exxjxw.hannivoort@inter.nl.net> - 2016-02-28 23:07 +0100
      Re: Refer object within itself "Evertjan." <exxjxw.hannivoort@inter.nl.net> - 2016-02-28 23:23 +0100
        Re: Refer object within itself Stefan Weiss <krewecherl@gmail.com> - 2016-02-29 00:11 +0100
        Re: Refer object within itself Aleksandro <aleksandro@gmx.com> - 2016-02-29 14:49 -0300
          Re: Refer object within itself "Evertjan." <exxjxw.hannivoort@inter.nl.net> - 2016-02-29 19:49 +0100
            Re: Refer object within itself Aleksandro <aleksandro@gmx.com> - 2016-03-01 10:48 -0300
              Re: Refer object within itself "Evertjan." <exxjxw.hannivoort@inter.nl.net> - 2016-03-01 17:22 +0100
                Re: Refer object within itself Aleksandro <aleksandro@gmx.com> - 2016-03-01 15:07 -0300
                Re: Refer object within itself "Evertjan." <exxjxw.hannivoort@inter.nl.net> - 2016-03-01 20:26 +0100
                Re: Refer object within itself Aleksandro <aleksandro@gmx.com> - 2016-03-04 21:53 -0300
                Re: Refer object within itself "Evertjan." <exxjxw.hannivoort@inter.nl.net> - 2016-03-05 14:22 +0100
                Re: Refer object within itself Scott Sauyet <scott.sauyet@gmail.com> - 2016-03-05 10:17 -0800
                Re: Refer object within itself "Evertjan." <exxjxw.hannivoort@inter.nl.net> - 2016-03-06 11:59 +0100
                Re: Refer object within itself Ram Tobolski <ramtob@gmail.com> - 2016-03-06 10:48 -0800
                Re: Refer object within itself Scott Sauyet <scott.sauyet@gmail.com> - 2016-03-06 19:07 -0800
                Re: Refer object within itself "Evertjan." <exxjxw.hannivoort@inter.nl.net> - 2016-03-07 10:44 +0100
                Re: Refer object within itself Aleksandro <aleksandro@gmx.com> - 2016-03-07 12:54 -0300
                Re: Refer object within itself "Evertjan." <exxjxw.hannivoort@inter.nl.net> - 2016-03-07 17:59 +0100
                Re: Refer object within itself Scott Sauyet <scott.sauyet@gmail.com> - 2016-03-07 13:44 -0800
                Re: Refer object within itself "Evertjan." <exxjxw.hannivoort@inter.nl.net> - 2016-03-07 22:59 +0100
                Re: Refer object within itself Scott Sauyet <scott.sauyet@gmail.com> - 2016-03-07 17:00 -0800
                Re: Refer object within itself "Evertjan." <exxjxw.hannivoort@inter.nl.net> - 2016-03-08 10:24 +0100
                Re: Refer object within itself Scott Sauyet <scott.sauyet@gmail.com> - 2016-03-08 13:03 -0800

csiph-web