2011-06-17 15 views
0

美好的一天,首先我想告诉大家,我不自豪地发布整个源代码。我无法在较小的块中找出问题。这是如何“通过”,但实际上它不应该?

这里是文件的快照:

getRoomById : function(areaId, roomId) { 
    if (this.hAreas.get(areaId) !== null && this.hAreas.get(areaId)[ roomId ] !== undefined) 
    { 
     //I can get here... 
     //alert(uneval(this.hAreas.get(areaId))); 
     // returns: ({'000001':{areaId:"000001", roomId:"000001", Informations:{Name:"Room 1"}}, '000002':{areaId:"000001", roomId:"000002", Informations:{Name:"Room 2"}}, '000003':{areaId:"000001", roomId:"000003", Informations:{Name:"Room 3"}}}) 

     //alert(roomId); 
     // returns: 000003 

     return this.hAreas.get(areaId)[ roomId ]; 
     // returns: undefined 
    } 
}, 

和整个文件是存在的:http://jsfiddle.net/JSWCu/2/

问题:我有哪些测试针对JS.Hash的参数包含对象的方法。该if希望返回true,但一旦进入,我不能得到(要么提醒或返回)该对象JS.Hash(未定义返回)。

谢谢!非常感谢您的帮助。我也希望提示,以避免这种错误。

编辑:这是整个代码。对不起它真的很大。这只是开始变得复杂,我不能(现在)隔离的问题,一个较小的一块代码:

<html> 
    <head> 
     <style type="text/css"> 

     </style> 
     <script type="text/javascript"> 
      JSCLASS_PATH = 'http://www.poc.ca/cybrix/src'; 
      function appendConsole(input) { 
       document.getElementById("console").innerHTML += input + "<br />"; 
      } 
     </script> 
     <script type="text/javascript" src="http://www.poc.ca/cybrix/src/loader-browser.js"></script> 
     <script type="text/javascript"> 
      JS.require('JS.Hash', 'JS.Observable', function() { 
       var AreaLists = { 
        "000001" : { "Name" : "Test Area", "Loaded" : false }, 
       }; 

       var World = new JS.Class({ 
        hAreas : new JS.Hash([]), 

        getAreas : function(areaId) { 
         if (! this.hAreas.get(areaId) && AreaLists[ areaId ] !== undefined) 
         { 
          //TODO: Load from external sources 

          this.hAreas.put(areaId, { 
           "000001" : new Room(areaId, "000001", { "Name" : "Room 1" }), 
           "000002" : new Room(areaId, "000002", { "Name" : "Room 2" }), 
           "000003" : new Room(areaId, "000003", { "Name" : "Room 3" }), 
          }); 

          AreaLists[ areaId ].Loaded = true; 

          appendConsole("Areas #" + areaId + " : " + AreaLists[ areaId ].Name + " Created"); 
         } 

         return this.hAreas.get(areaId); 
        }, 
        getRoomById : function(areaId, roomId) { 
         if (this.hAreas.get(areaId) !== null && this.hAreas.get(areaId)[ roomId ] !== undefined) 
         { 
          //I can get here... 
          //alert(uneval(this.hAreas.get(areaId))); 
          // returns: ({'000001':{areaId:"000001", roomId:"000001", Informations:{Name:"Room 1"}}, '000002':{areaId:"000001", roomId:"000002", Informations:{Name:"Room 2"}}, '000003':{areaId:"000001", roomId:"000003", Informations:{Name:"Room 3"}}}) 

          //alert(roomId); 
          // returns: 000003 

          return this.hAreas.get(areaId)[ roomId ]; 
          // returns: undefined 
         } 
        }, 
        reloadAreas : function(areaId) { 
         //Triggered by Tick only if there is no players 
        }, 

        addCharacter : function(areaId, roomId, character) { 
         if (this.hAreas.get(areaId) && this.hAreas.get(areaId)[ roomId ]) 
         { 
          this.hAreas.get(areaId)[ roomId ].addCharacter(character); 
         } 
        }, 
        removeCharacter : function(areaId, roomId, character) { 
         return this.hAreas.get(areaId)[ roomId ].removeCharacter(character); 
        } 
       }); 

       var Room = new JS.Class({ 
        hDoors : new JS.Hash([]), 
        hExits : new JS.Hash([]), 
        hBodies : new JS.Hash([]), 
        hObjects : new JS.Hash([]), 

        initialize : function(areaId, roomId, Informations) { 
         this.areaId = areaId; 
         this.roomId = roomId; 
         this.Informations = Informations; 

         //TODO: Load from external sources 
         if (areaId == "000001" && roomId == "000003") 
         { 
          this.hObjects.put("000001", new Objects("000001", { "Name" : "A table", "Type" : 0 })); 
          this.hObjects.put("000002", new Objects("000002", { "Name" : "A water fountain", "Type" : 1 })); 
         } 

         appendConsole("Room: #" + this.areaId + "-" + this.roomId + " : " + this.Informations.Name + " Created"); 
        }, 

        addCharacter : function(character) { 
         this.hBodies.put(character.characterId , character); 

         character.onArriveRoom(this); 

         if (! character.Informations.Stealth) 
         { 
          //TODO: Broadcast Informations to others 

          appendConsole(character.Informations.Name + " has arrived to " + this.Informations.Name); 
         } 
        }, 
        removeCharacter : function(character) { 
         var characterId = (typeof character == "object") ? character.characterId : character, 
          currentCharacter = this.hBodies.remove(characterId); 

         character.onLeaveRoom(this); 

         if (currentCharacter !== null) 
         { 
          //TODO: Broadcast Informations to others 

          appendConsole(character.Informations.Name + " has left " + this.Informations.Name); 

          return currentCharacter; 
         } 

         return undefined; 
        }, 

        onArrive : function() { 

        }, 

        onLeave : function() { 

        }, 

        getObjects : function(objectId, hash) { 
         if (this.hObjects.get(objectId)) 
         { 
          var currentObjects = this.hObjects.get(objectId); 

          if (hash) 
          { 
           return new JS.Hash([ 
            currentObjects.objectId, currentObjects 
           ]); 
          } 

          return currentObjects; 
         } 

         return this.hObjects; 
        }, 

        toString : function(characterId) { 

        } 
       }); 

       var Objects = new JS.Class({ 
        objectsTypes : { 
         0 : "lies", 
         1 : "stands" 
        }, 

        initialize : function(objectId, Informations) { 
         this.objectId = objectId; 
         this.Informations = Informations; 

         appendConsole("Object: #" + this.objectId + " : " + this.Informations.Name + " Created"); 
        }, 

        toString : function() { 
         return this.Informations.Name + " " + this.objectsTypes[ this.Informations.Type ] + " here."; 
        } 
       }); 

       var Character = new JS.Class({ 
        Pet : undefined, 

        initialize : function(characterId, Informations) { 
         this.characterId = characterId; 
         this.Informations = Informations; 
         this.areaId = this.Informations.Zone.split("-")[ 0 ]; 
         this.roomId = this.Informations.Zone.split("-")[ 1 ]; 

         if (this.Informations.Pet !== undefined) 
         { 
          //TODO: Load from external sources 

          if (this.Informations.Pet === "000001") 
          { 
           this.Pet = new Pet("000001", { "Name" : "Molten Panther", "Zone" : this.areaId + "-" + this.roomId, "Stealth" : false }); 

           World.addCharacter(this.Pet.getArea() , this.Pet.getRoom() , this.Pet); 

           var petRoom = World.getRoomById(this.Pet.getArea() , this.Pet.getRoom()); 

           alert(petRoom); // = undefined ???? 
          } 
         } 

         appendConsole("Character: #" + this.characterId + " : " + this.Informations.Name + " Created"); 
        }, 

        onArriveRoom : function (currentRoom) { 

        }, 
        onLeaveRoom : function(currentRoom) { 

        }, 

        onArrive : function() { 

        }, 
        onLeave : function() { 

        }, 

        getRoom : function() { 
         return this.roomId + ""; 
        }, 
        getArea : function() { 
         return this.areaId + ""; 
        }, 
        getInformations : function() { 
         return this.Informations; 
        }, 
        hasPet : function() { 
         return (typeof this.Pet == "object"); 
        }, 
        getPet : function() { 
         return this.Pet; 
        }, 

        equals : function(character) { 
         return (character instanceof this.klass) && character.Informations.Name === this.Informations.Name; 
        } 
       }); 

       var Pet = new JS.Class(Character, { 

        initialize : function(characterId, Informations) { 
         this.callSuper(); 

         appendConsole("Pet: " + this.Informations.Name + " Created"); 
        } 
       }); 

       //Tests 
       var World = new World(); 
       var AreaOne = World.getAreas("000001"); 

       var Cybrix = new Character("000001", { "Name" : "Cybrix", "Zone" : "000001-000003", "Stealth" : false, "Pet" : "000001" }); 

       if (World.getAreas(Cybrix.getArea())) 
       { 
        World.addCharacter(Cybrix.getArea() , Cybrix.getRoom() , Cybrix); 

        //Cybrix = World.removeCharacter(Cybrix.getArea() , Cybrix.getRoom() , Cybrix); 
       } 
      }); 
     </script> 
    </head> 
    <body style="margin: 0; padding: 0;"> 
     <div id="console" style="display: block; background-color: #000; height: 100%; color: #FFF; font-family: Lucida Console;"></div> 
    </body> 
</html> 
+3

然而,尽管它很大,请在StackOverflow上发布* entire *问题。实时链接对于一个问题来说是一个很好的*附件*,但总是在问题*中发布相关的代码*。两个原因。 1.人们不应该遵循链接来帮助你。 2. StackOverflow不仅适用于您,而且适用于将来也有类似问题的其他人。外部链接可以被移动,修改,删除等。通过确保相关代码在问题中,我们确保问题(及其答案)在合理的时间段内保持有用。 –

+3

哦:并且不断尝试创建一个(更小),自包含的示例。 :-) –

+1

@ T.J .:对第二条评论无法表示赞同;) –

回答

1

我一直在玩jsfiddle上的例子,我遇到了一些相当奇怪的行为。在Characterinitialization方法中,您将调用World.getRoomById()方法并将其分配给名为petRoom的变量。

随着你的代码的立场,当你alert(petRoom)你确实得到undefined。然而,如果你alert(petRoom.roomId)你得到000003如预期的,所以我的猜测是它不是真的返回true未定义。如果你将petRoom登录到chrome的控制台,它将它分类为构造函数而不是对象。我不确定那里发生了什么,但我认为它会给一些额外的方向。我会继续玩......

UPDATE:的问题是,你重写Room类的toString()方法,而不是返回任何东西。默认情况下,警告某事使用对象的toString()方法将其转换为字符串,并且由于您已覆盖该方法并且未返回未定义的值。

var Room = new JS.class({ 
     ... 
     snip 
     .... 
     toString: function(characterId) { 

     } 
}); 
+0

确实。我也可以访问petRoom,就好像它是对象本身一样。我现在很困惑... – Cybrix

+0

你只需要删除你的Room类中的overriden toString()方法或让它返回一些东西。 World.getRoomById正在返回你的对象,它没有返回undefined。当您警觉时,您只会看到未定义,因为警报使用您已覆盖的对象的toString()方法。 – WesleyJohnson

+1

哦......废话......谢谢! – Cybrix

0

试试这个:

typeof this.hAreas.get(areaId)[ roomId ] !== "undefined" 
+1

'typeof'总是返回一个字符串:) –

+0

@Felix Kling:谢谢,更新:) – Town

1

回答你的问题的意见

怎么可能if通行证时,一旦你返回值是未定义

您正在使用比较this.hAreas.get(areaId)[ roomId ] !== undefined。那将做的是测试左边的值不是严格等于到那个特定的undefined实例。如果您处理多个窗口/框架,则可能有不同的undefined实例(因为每个窗口都有自己的undefined)。如果这听起来很奇怪,那是因为它。

为了防止这一点,你通常可以看到比较写成:

if (typeof this.hAreas.get(areaId)[ roomId ] !== "undefined") 

...哪些测试的操作数的类型是“不确定”(注意引号),这是可靠的跨窗口。

相关问题