Это для собеседования при приеме на работу, и мне бы очень хотелось, если бы кто-то мог взглянуть на это и сказать, делаю ли я какие-либо большие ошибки. Здесь был вопрос:
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 это все еще не работает ... если я приду к окончательной реализации, которая будет работать, я опубликую ее.