2009-09-17 36 views
1

這是一次求職面試,如果有人能夠在這個問題上留下一個眼球,並說我是否犯了大錯,我很樂意。這裏曾是一個問題:這是一個體面的JavaScript反射示例實現?

1)假設我們正在開發一個基於JS- 調試器,類似於Firebug的,我們 需要一種方法來檢查JS對象和 元素。編寫一個路由,它將一個對象/元素作爲輸入,並將 列出其屬性(如 屬性,方法等),值和 數據類型。

這裏是我的實現:

var printObjectReflection = function(showPrototypeChainProperties){ 

    // Default: false 
    showPrototypeChainProperties = 
     typeof(showPrototypeChainProperties) != 'undefined' ? showPrototypeChainProperties : false; 

    var objToReflect = this; 

    // Create and populate collections for different lists 
    var methodPropertyList = Array(); 
    var arrayPropertyList = Array(); 
    var objectPropertyList = Array(); 
    var scalarPropertyList = Array(); 

    for (property in objToReflect) { 

     var propertyName = property; 
     var propertyValue = objToReflect[property]; 
     var propertyType = typeof(objToReflect[property]); 
     // For telling integer indexed arrays from other types of objects 
     var isArray = objToReflect[property] instanceof Array; 

     // Makes sure this is an actual property of the object and not something 
     // from the prototype chain, unless show is specified 
     if (objToReflect.hasOwnProperty(property) || showPrototypeChainProperties){ 

      // 
      // Routing to populate lists: 
      // 

      // Methods 
      if (propertyType === 'function') { 
       methodPropertyList.push({"propertyName" : propertyName}) 

      // Arrays and other objects 
      } else if (propertyType === 'object') {   
       if (isArray) { 
        arrayPropertyList.push({"propertyName" : propertyName})  
       } else { 
        objectPropertyList.push({"propertyName" : propertyName}) 
       } 

      // Scalar member variables 
      } else { 

       scalarPropertyList.push({ 
        "propertyName" : propertyName, 
        "propertyValue" : propertyValue, 
        "propertyType" : propertyType 
       }) 

      } 
     } 

    } 

    // 
    // Cheap and dirty display 
    // In real life, this would populate some kind of console or log 
    // instead of simple document.write's 
    // 

    document.write('<h3>Methods in this object:</h3>'); 
    if (methodPropertyList.length > 0) { 
     var i; 
     for (i = 0; i < methodPropertyList.length; i += 1) { 
      document.writeln("<strong>Method name:</strong> " + 
          methodPropertyList[i].propertyName + "<br />"); 
     } 
    } else { 
     document.writeln("No methods. <br /><br />"); 
    } 

    document.write('<h3>Arrays in this object:</h3>'); 
    if (arrayPropertyList.length > 0) { 
     var i; 
     for (i = 0; i < arrayPropertyList.length; i += 1) { 
      document.writeln("<strong>Array name:</strong> " + 
          arrayPropertyList[i].propertyName + 
          "<br />"); 
     } 
    } else { 
     document.writeln("No arrays. <br /><br />");  
    } 

    document.write('<h3>Non-array objects in this object:</h3>'); 
    if (objectPropertyList.length > 0) { 
     var i; 
     for (i = 0; i < objectPropertyList.length; i += 1) { 
      document.writeln("<strong>Object name:</strong> " + 
          objectPropertyList[i].propertyName + 
          "<br />"); 
     } 
    } else { 
     document.writeln("No objects. <br /><br />"); 
    } 

    document.write('<h3>Scalars for this object:</h3>'); 
    if (scalarPropertyList.length > 0) { 
     var i; 
     for (i = 0; i < scalarPropertyList.length; i += 1) { 
      document.writeln("<strong>Name:</strong> " + 
          scalarPropertyList[i].propertyName + 
          " | <strong>Value:</strong> " + 
          scalarPropertyList[i].propertyValue + 
          " | <strong>Data type:</strong> " + 
          scalarPropertyList[i].propertyType + 
          "<br />"); 
     } 
    } else { 
     document.writeln("No scalar variables. <br /><br />"); 
    } 

} // end function 

和樣品使用:

<h2>DOM Element to look for:</h2> 
<input id="inputElementToLookFor" type="text" value="monkeyShines" /> 

<h2>A created object literal:</h2> 
<script type="application/javascript"> 
// An object we created 
var testObj = { 
    'first-name' : "dan", 
    'aNumber' : 234, 
    'anArray' : [1,2,3,4], 
    'anObject' : {"one":1, "two":2}, 
    'aMethod' : function() {} 
}; 

testObj.printObjectReflection = printObjectReflection; 
testObj.printObjectReflection(); 
</script> 

<h2>An HTML element we pulled from the DOM: </h2> 
<script> 
// An HTML element 
var myInputElement = document.getElementById("inputElementToLookFor") 
myInputElement.printObjectReflection = printObjectReflection; 
myInputElement.printObjectReflection(true); 
</script> 

任何令人難以置信的愚蠢的錯誤,任何人都可以發現?預先感謝熟練的眼球。

編輯:好的,這是我的修訂實施。我做最終只是完全徹底消除了hasOwnProperty檢查,因爲它似乎非常嗆IE,它不是真正的需求的一部分,以限制基於hasOwnProperty:

var printObjectReflection = function(objToReflect){ 

    // Create and populate collections for different lists 
    var methodPropertyList = []; 
    var arrayPropertyList = []; 
    var objectPropertyList = []; 
    var scalarPropertyList = [];  

    for (property in objToReflect) { 

     var propertyName = property; 
     var propertyValue = objToReflect[property]; 
     var propertyType = typeof(objToReflect[property]); 
     // For telling integer indexed arrays from other types of objects 
     var isArray = objToReflect[property] instanceof Array; 

     // 
     // Routing to populate lists: 
     // 

     // Methods 
     if (propertyType === 'function') { 
      methodPropertyList.push({"propertyName" : propertyName}) 

     // Arrays and other objects 
     } else if (propertyType === 'object') {   
      if (isArray) { 
       arrayPropertyList.push({"propertyName" : propertyName})  
      } else { 
       objectPropertyList.push({"propertyName" : propertyName}) 
      } 

     // Scalar member variables 
     } else { 

      scalarPropertyList.push({ 
       "propertyName" : propertyName, 
       "propertyValue" : propertyValue, 
       "propertyType" : propertyType 
      }) 

     } 
    } 

    // 
    // Cheap and dirty display 
    // In real life, this would populate some kind of console or log 
    // instead of simple document.write's 
    // 

    document.write('<h3>Methods in this object:</h3>'); 
    if (methodPropertyList.length > 0) { 
     var i; 
     for (i = 0; i < methodPropertyList.length; i += 1) { 
      document.writeln("<strong>Method name:</strong> " + 
          methodPropertyList[i].propertyName + "<br />"); 
     } 
    } else { 
     document.writeln("No methods. <br /><br />"); 
    } 

    document.write('<h3>Arrays in this object:</h3>'); 
    if (arrayPropertyList.length > 0) { 
     var i; 
     for (i = 0; i < arrayPropertyList.length; i += 1) { 
      document.writeln("<strong>Array name:</strong> " + 
          arrayPropertyList[i].propertyName + 
          "<br />"); 
     } 
    } else { 
     document.writeln("No arrays. <br /><br />");  
    } 

    document.write('<h3>Non-array objects in this object:</h3>'); 
    if (objectPropertyList.length > 0) { 
     var i; 
     for (i = 0; i < objectPropertyList.length; i += 1) { 
      document.writeln("<strong>Object name:</strong> " + 
          objectPropertyList[i].propertyName + 
          "<br />"); 
     } 
    } else { 
     document.writeln("No objects. <br /><br />"); 
    } 

    document.write('<h3>Scalars for this object:</h3>'); 
    if (scalarPropertyList.length > 0) { 
     var i; 
     for (i = 0; i < scalarPropertyList.length; i += 1) { 
      document.writeln("<strong>Name:</strong> " + 
          scalarPropertyList[i].propertyName + 
          " | <strong>Value:</strong> " + 
          scalarPropertyList[i].propertyValue + 
          " | <strong>Data type:</strong> " + 
          scalarPropertyList[i].propertyType + 
          "<br />"); 
     } 
    } else { 
     document.writeln("No scalar variables. <br /><br />"); 
    } 

} // end function 

而新的呼叫:

<h2>DOM Element to look for:</h2> 
<input id="inputElementToLookFor" type="text" value="monkeyShines" /> 

<h2>A created object literal:</h2> 
<script type="application/javascript"> 
// An object we created 
var testObj = { 
    'first-name' : "dan", 
    'aNumber' : 234, 
    'anArray' : [1,2,3,4], 
    'anObject' : {"one":1, "two":2}, 
    'aMethod' : function() {} 
}; 

printObjectReflection(testObj); 
</script> 

<h2>An HTML element we pulled from the DOM: </h2> 
<script> 
// An HTML element 
var myInputElement = document.getElementById("inputElementToLookFor") 
printObjectReflection(myInputElement); 
</script> 

感謝大家的幫助。它仍然不能在IE中工作,可悲的是......如果我想出一個最終的實現,我會發布它。

+1

我*認爲*你的大錯誤可能一直在一個論壇上提供你的求職面試問題,該論壇被谷歌索引。 (請參閱http://www.google.com/search?q="Assume+we're+developing+a+JS-based+debugger「)遲早有人可能會注意到您在此處選擇瞭解答? – 2009-09-17 19:36:55

回答

1

該代碼看起來沒問題。如果你真的想給他們留下深刻印象,可以考慮將結果查看器放在一起,將信息呈現在列表(或表)中,並允許點擊對象和數組,然後將它們顯示在嵌套列表(或表)中。

對於面試問題看起來似乎有點矯枉過正,但實際上這很簡單,並且對DOM有很好的理解。

更重要的是,它提供了一些提示面試官進一步的問題。記住:他們只會有一定的時間,而這將使他們的問題集中在一塊你完全理解的代碼上,從而減少他們用一個你不太瞭解的問題打你的風險。

你越能得到他們花時間談論你自己的代碼,更加自信,你會感覺和更好的機會:-)

編輯:從乍得的有關IE錯誤評論下面就,我反對使用反射方法,將函數添加爲被檢查對象的屬性,然後迭代this - 除了其他任何內容外,它表示該函數將顯示爲一個屬性,並修改「重新檢查是一個壞主意。只需將該項目作爲參數傳遞給函數 - 我可以恭敬地提出名稱that作爲參數。

+0

謝謝,實施它作爲一個參數。同意這是一個更好的解決方案。至於一個閃爍的顯示:我正在與時鐘戰鬥。 – danieltalsky 2009-09-17 17:53:53

1

使用[]而不是Array(),因爲可以覆蓋數組。

1

在實現此行導致在IE

錯誤

myInputElement.printObjectReflection = printObjectReflection;