문제

Beginner JavaScript question. I'm sort of spoiled on the dir built-in function from Python. I want to discover the properties/methods of any object in the node.js REPL. I have already seen this question; the accepted answer fails (in the node REPL) in the simple case of an empty array []. For example:

for(var prop in []){console.log(prop);}  # returns undefined, prints nothing
[].length  # returns 0

Since the for loop does not discover the array's length method, I do not consider that to be proper introspection. So, could someone fill in the blank here:

function magic(some_object) {
  # magic goes here
}

console.log(magic([]))  # should print a list that includes 'length'

Or is this simply not possible, or only possible for "user types"?

도움이 되었습니까?

해결책

How far back do you need to go in browser compatibility? All of the modern browsers should support Object.getOwnPropertyNames(). Using your example, Object.getOwnPropertyNames([]) will return ["length"].

More info here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyNames

Edit: Other examples:

  • Object.getOwnPropertyNames([1, 2, 3]); returns ["0", "1", "2", "length"]

  • Object.getOwnPropertyNames(String); returns ["prototype", "quote", "substring", "toLowerCase", "toUpperCase", "charAt", "charCodeAt", "contains", "indexOf", "lastIndexOf", "startsWith", "endsWith", "trim", "trimLeft", "trimRight", "toLocaleLowerCase", "toLocaleUpperCase", "localeCompare", "match", "search", "replace", "split", "substr", "concat", "slice", "fromCharCode", "length", "name", "arguments", "caller"]

Edit #2: Okay, so seeing that you are looking for complete list of properties and methods, including inherited ones, I've borrowed from two other SO questions (linked below) and come up with a solution that appears to get you even closer:

var findProperties = function(obj) {
    var aPropertiesAndMethods = [];

    do {
        aPropertiesAndMethods = aPropertiesAndMethods.concat(Object.getOwnPropertyNames(obj));
    } while (obj = Object.getPrototypeOf(obj));

    for ( var a = 0; a < aPropertiesAndMethods.length; ++a) {
        for ( var b = a + 1; b < aPropertiesAndMethods.length; ++b) {
            if (aPropertiesAndMethods[a] === aPropertiesAndMethods[b]) {
                aPropertiesAndMethods.splice(a--, 1);
            }
        }
    }

    return aPropertiesAndMethods;
}

So if you use call findProperties([]), it returns ["length", "join", "reverse", "sort", "push", "pop", "shift", "unshift", "splice", "concat", "slice", "lastIndexOf", "indexOf", "forEach", "map", "reduce", "reduceRight", "filter", "some", "every", "iterator", "constructor", "toSource", "toString", "toLocaleString", "valueOf", "watch", "unwatch", "hasOwnProperty", "isPrototypeOf", "propertyIsEnumerable", "__defineGetter__", "__defineSetter__", "__lookupGetter__", "__lookupSetter__"]

Linked Questions

javascript inheritance, reflection and prototype chain walking?

How to merge two arrays in Javascript and de-duplicate items

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top