首页 > 解决方案 > Javascript 属性不能引用同一对象的属性

问题描述

我声明这个对象:

var layout = {
    menu: {
        type: 0,
        x: 50,
        y: 50,
        w: 50,
        h: 50
    },

    name: {
        type: 2,
        str: "name",
        x: 50+layout.menu.x,
        y: 40+layout.menu.y,
        h: 25
    }
}

但是由于某种原因,当试图引用“layout.menu”时,控制台会尖叫它是未定义的,而它在它之前是明确定义的。任何人都可以解释为什么会这样吗?

标签: javascriptreferencejavascript-objects

解决方案


该变量layout仅在首先评估赋值的右侧部分时才接收其值。只有评估之后才会进行分配layout。需要评估整个对象文字(直到您引用的代码结束)。在赋值发生之前,即使在对象字面量的评估期间,变量layout仍然是未定义的。因此,在对象字面量中对它的任何引用都将是未定义的。

要解决此问题,请使用增量方法:

var layout = {
    menu: {
        type: 0,
        x: 50,
        y: 50,
        w: 50,
        h: 50
    }
};
// At this moment layout has a value with the "menu" property. So we continue:
layout.name = {
    type: 2,
    str: "name",
    x: 50+layout.menu.x,
    y: 40+layout.menu.y,
    h: 25
};

如果您打算对and的值进行实时引用,以便这些属性的任何更新都会立即反映在结构中,那么您需要一个函数,它可以是一个 getter:menu.xmenu.yname

var layout = {
    menu: {
        type: 0,
        x: 50,
        y: 50,
        w: 50,
        h: 50
    },
    name: {
        type: 2,
        str: "name",
        get x() { return 50+layout.menu.x },
        get y() { return 40+layout.menu.y },
        h: 25
    }
};

// Demo
console.log(layout.name.x);

但是,如果您只想解决初始引用问题,则不建议将其作为解决方案,因为使用此解决方案每次读取 的值时layout.name.x,都会执行 getter 函数,这是不必要的开销。


推荐阅读