Kriem
Kriem

Reputation: 8705

Dynamic Getters and Setters - Why doesn't this work?

I'm trying to create an object that builds its own getters and setters dynamically:

function Person( properties ) { // 'properties' is an object literal

    this._private = properties; // private by convention

    for ( key in this._private ) {

        this[key] = function() {

            return this._private[key];
        }
    }
}

I hoped, this would create something like this:

var jack = new Person({

    working:true,
    age:33,
    gender:'male'
});

jack.working() --> true
jack.age() --> 33
jack.gender() --> 'male'

The problem is, it always returns 'male', like so:

jack.working() --> 'male'
jack.age() --> 'male'
jack.gender() --> 'male'

What am I missing? Oh, and this is just a proof of concept. I know this is not a perfect solution for creating getters and setters in JavaScript.

Upvotes: 2

Views: 469

Answers (2)

Andrew Whitaker
Andrew Whitaker

Reputation: 126072

You've got a classic scoping issue. Create a new function to create scope around key:

function Person(properties) { // 'properties' is an object literal
    var key;

    this._private = properties; // private by convention
    this.buildGetter = function (key) {
        this[key] = function () {
            return this._private[key];
        }
    };
    for (key in this._private) {
        this.buildGetter(key);
    }
}

Example: http://jsfiddle.net/SEujb/

Upvotes: 7

PitaJ
PitaJ

Reputation: 15084

Everybody says eval is evil, but sometimes it can't be avoided:

function Person( properties ) { // 'properties' is an object literal

    this._private = properties; // private by convention

    for ( key in this._private ) {

        eval("this[key] = function() { return this._private['"+key.toString()+"'];}");
    }
}

jsFiddle: http://jsfiddle.net/pitaj/9sWbe/1/

Upvotes: 3

Related Questions