JavaScript中对象内的对象

35

我对Javascript还比较新手,也许这只是一个初学者的错误,但我在查找时没有发现任何特别有帮助的东西。我正在编写一个游戏,并尝试构建一个暂停菜单对象。

我想做的其中一件事是使菜单上的按钮成为暂停菜单对象内的对象,以方便组织管理。最终我会添加事件处理程序到这些对象中,我也想在暂停菜单对象内完成这些操作。有些按钮还没有完全编码好,但我想至少让一些东西在继续之前可以正常工作。

我使用 Raphael.js v1.5.2 来渲染形状。Raphael 的其他部分都可以工作,但与此不同的代码看起来不太令人愉快,所以我希望类似于这种代码。

目前我的问题是,当我执行 var pause_menu = new pause_menu(); 时,实际上什么都没有呈现。

这是我目前为暂停菜单编写的代码:

//Pause Menu Object:
function pause_menu() {

    function pause_button() {
        this.button = game.rect(0, 350, 150, 50, 5);
        this.text =  game.text(75, 375, 'PAUSE');
    }
    function resume_button() {
        this.button;
        this.text;
    }
    function quit_button() {
        this.button;
        this.text;
    }
    this.pause_button = new pause_button(); //the button that the user presses to pause the game (I want an event handler on this to trigger .show() method for presently hidden menu items)
    this.resume_button = new resume_button();
    this.quit_button = new quit_button();
    this.box = game.rect(150, 50, 400, 300, 5).hide(); //the box that surrounds the menu when it appears
}
var pause_menu = new pause_menu();

好的,这是解决方案(带有事件处理程序):

var pause_menu = {

    pause_button: { button : game.rect(0, 350, 150, 50, 5).click(function (event){
                       pause_menu.menu_box.show();
                  }), text : game.text(75, 375, 'PAUSE') },
    menu_box: game.rect(150, 50, 400, 300, 5).hide(),
    resume_button: {},
    quit_button: {}

};

看起来你需要创建一个render()方法来渲染game.rect()实例? - Nathan Romano
我建议您查看这个SO答案 - Lance
不确定问题出在哪里,没有其他代码,但请注意,当您在与函数相同的变量作用域中执行var pause_menu = new pause_menu();时,会覆盖您的pause_menu函数。 - user113716
谢谢Patrick,实际游戏中var pause_menu = new pause_menu();不在同一作用域内。它是否被覆盖是因为变量名与函数名相同? - Michael Taufen
2个回答

40
var pause_menu = {
    pause_button : { someProperty : "prop1", someOther : "prop2" },
    resume_button : { resumeProp : "prop", resumeProp2 : false },
    quit_button : false
};

然后:

pause_menu.pause_button.someProperty //evaluates to "prop1"

等等,等等。


11
那不是JSON,它们只是对象字面量。这是常见的错误。 - user113716
这个和Lance的回答的结合解决了问题,谢谢你们! - Michael Taufen

24
你可以拥有任意多层的对象层级,只要你将一个对象声明为另一个父对象的属性即可。注意每个层级上逗号的位置,这是比较棘手的部分。在每个层级的最后一个元素后面不要使用逗号:

{el1, el2, {el31, el32, el33}, {el41, el42}}

var MainObj = {

  prop1: "prop1MainObj",
  
  Obj1: {
    prop1: "prop1Obj1",
    prop2: "prop2Obj1",    
    Obj2: {
      prop1: "hey you",
      prop2: "prop2Obj2"
    }
  },
    
  Obj3: {
    prop1: "prop1Obj3",
    prop2: "prop2Obj3"
  },
  
  Obj4: {
    prop1: true,
    prop2: 3
  }  
};

console.log(MainObj.Obj1.Obj2.prop1);


1
JavaScript中的尾随逗号是可以的。自ES5(我认为甚至是ES3)以来,它已经在ECMA-Script规范中了。但是,IE8及以下版本不支持此功能,因此在遇到“悬空逗号”时会出错。总之,使用逗号作为最后一个元素的结束符是完全可以的。事实上,现在通常更喜欢这样做。 - the chad
@thechad 为什么在对象的最后一个元素使用尾随逗号更可取? - Aónio
2
@Aónio,不管怎样都不是什么大问题。在我看来,能够添加新的键值而无需记得先添加逗号是很好的(尾随逗号也可以,但忘记用逗号分隔确实是错误)。说常常“首选”可能有点过了,也许更准确的说法是“常见做法”。 “首选”似乎使它听起来比实际情况重要。 - the chad
1
JSON中的尾随逗号。对象中的尾随逗号仅在ECMAScript 5中引入。由于JSON基于ES5之前的JavaScript语法,因此JSON中不允许使用尾随逗号。我刚找到这个解释,我的评论是针对这篇特定的帖子,作者在使用对象字面量而不是JSON。只是想澄清这一点。 - the chad
@thechad 我认为出于教学目的,我们不应该让读者感到困惑。尾随逗号是“可以接受的”,但可能会导致混淆,就像你在JSON中所说的那样,甚至在数组 var arr = [1, 2,] 中也是如此。 - Aónio

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接