Search code examples
javascriptloopsobjectfor-loopdefineproperty

Object.defineProperty in for loop


In my code I have an object,

var obj = {
    item1: {
        coords: {
            A: new Point(905.76, 1626.67),
            //...
        },
        inf: {
            //...
        }
    },

    item2: {
        coords: {
            A: new Point(1259.25, 1634.50),
            //...
        },
        inf: {
            //...
        }
    },
}

And I would like to define some properties like that:

Object.defineProperty(obj.item1.inf, "corner", {
    get() {
        var x = obj.item1.coords.A.x;
        var y = obj.item1.coords.A.y;
        return new Point(x, y);
    }
})
Object.defineProperty(obj.item2.inf, "corner", {
    get() {
        var x = obj.item2.coords.A.x;
        var y = obj.item2.coords.A.y;
        return new Point(x, y);
    }
})

It works fine for me, but it's only a piece of code. I thought, that it'll be nicer to make my code shorter and I decided to instead of just copying and renamed it uses a for loop like that:

for (item in obj) {
    Object.defineProperty(obj[item].inf, "corner", {
        get() {
            var x = obj[item].coords.A.x;
            var y = obj[item].coords.A.y;
            return new Point(x, y);
        }
    })
}

But it just one issue. I'm getting the same values for all items inf from the last one. Is there any possibility to solve this problem?


Solution

  • I think the problem is the lack of closure in your loop (you can read more about this here). The simplest solution is to define your loop variable with let which creates block scope variable:

    for (let item in obj) {
        Object.defineProperty(obj[item].inf, "corner", {
            get() {
                var x = obj[item].coords.A.x;
                var y = obj[item].coords.A.y;
                return new Point(x, y);
            }
        })
    }