这是一次求职面试,如果有人能关注这件事并说我有什么大错误的话,我会很高兴的。问题是:
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>
任何人都能发现的愚蠢的错误?提前感谢您的眼球。
编辑:
好的,这是我修订的实施。我最终完全取消了hasownpropy检查,因为它似乎让IE非常窒息,而且它不是基于hasownpropy的限制要求的一部分:
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>
谢谢大家的帮助。很遗憾,它仍然不起作用。如果我提出一个最终的实现,我会发布它。