0

I would like to set the property x when I first initialise my object, and then call Object.defineProperty. If I try to first access foo.x the console tells me that "value is not defined".

var foo = {x:20};

Object.defineProperty(foo, "x", {
    writeable: true,
    enumerable: true,
    configurable: true,
    get: function(){ 
      console.log("Get X value");
      return value;
     },
    set: function(newValue){
      console.log("Set X value");
      value = newValue;
    }
});
console.log(foo.x);  // **Uncaught ReferenceError: value is not defined** 
foo.x = 1;
console.log(foo.x);
foo.x = 10;
console.log(foo.x);
yvesb
  • 95
  • 9
  • Because `value` in your getter and setter are an undefined variable. Even if you want to "refer to itself" somehow, you'll have to define it. Check out [the examples on MDN about `object.defineProperty()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty#Creating_a_property). – Passerby Nov 28 '13 at 11:57

1 Answers1

0

Every property has a 'descriptor'. If you were to introduce this code below, you will see this...

var foo = {x:20};

var des = Object.getOwnPropertyDescriptor(foo,'x');
console.log('foo.x - descriptor =',des);

The descriptor for foo.x looks like this:

Object {
    value        : 20,
    writable     : true,
    enumerable   : true,
    configurable : true
}

As you can see configurable,enumerable and writable have already been pre-set to true, so there is no need to do this in defineProperty.


Also... If the descriptor has either get or set it CAN'T have either value or writable, and vice-versa, as this will cause an error like this:

Object.defineProperty(foo,'y',{
    value   : 5,
    get     : function(){return 10}
});

Will give the error:

Uncaught TypeError: Invalid property descriptor. Cannot both specify accessors and a value or writable attribute.

"accessors" being get & set.


I understand that you are trying to get/set the value of foo.x, but you have not defined anything to value yet. Something like, but NOT:

Object.defineProperty(foo, "x", {
    var value = this;

All-in-all you are going about this the wrong way. Take a look at this code and see if it helps:

var foo = {x:20};

Object.defineProperty(foo,'y',{
    get : function(){
        console.log('Get foo.x');
        return this.x;
    },
    set : function(val){
        console.log('Set foo.x');
        this.x = val;
    }
});

console.log(foo.x);     //  20
console.log(foo.y);     //  get foo.x (20)
foo.y = 10;             //  set foo.x to 10
console.log(foo.x);     //  10
console.log(foo.y);     //  10
LostInCyberSpace
  • 413
  • 4
  • 19