2011-06-17 18 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") 

...哪些測試的操作數的類型是「不確定」(注意引號),這是可靠的跨窗口。

相關問題