Search code examples
javascriptecmascript-5

Using getter and setter with Object.defineProperty


I want to convert a data property to accessor property using Object.defineProperty() . Consider the code for this which leads to Uncaught RangeError: Maximum call stack size exceeded error

var c = { name: 'abcde'};
Object.defineProperty(c, 'name', {
    get: function() {
        return this.name; //causes stack overflow
    },
    set: function(x) {
       this.name = x; //causes stack overflow
        }
}); 
c.name="xyz";  
console.log(c.name);

I understood why the error crops in. One of the proposed solution is to remove 'this' from getter and setter and it seems to work.

var c = { name: 'abcde'};
Object.defineProperty(c, 'name', {
    get: function() {
        return name; //removed this
    },
    set: function(x) {
       name = x; //removed this
        }
}); 
c.name="xyz";  
console.log(c.name);

What is happening ? In general , I want to ask how to convert a data property to accessor property using Object.defineProperty() ?


Solution

  • The second code doesn't actually work because it uses the global variable called name to store the value, instead of storing it in the object c.

    It would be rejected by ES5 "strict mode", if it weren't for the fact that window.name is a default property of the global object in browsers.

    A more appropriate fix would be to store the value in a lexically scoped private variable:

    var c = (function() {
        var obj = {};
        var name = "abcde";
    
        Object.defineProperty(obj, "name", {
            get: function() {
                return name;
            },
            set: function(x) {
                name = x;
            }
        });
    
        return obj;
    })();