Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript introspection that is complete

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"?

like image 272
wberry Avatar asked Jul 18 '13 20:07

wberry


People also ask

What is introspection in JavaScript?

Introspection is an important tool, especially for code interfacing with modern APIs over the Internet. It is a way of ensuring that the type (or class) of object can be processed in the appropriate way.

What is JavaScript's default object?

Note: Every JavaScript function has a prototype object property by default(it is empty by default).

Does JavaScript have reflection?

Reflect is a built-in object that provides methods for interceptable JavaScript operations. The methods are the same as those of proxy handlers. Reflect is not a function object, so it's not constructible.

How many built in methods are there in JavaScript?

JavaScript has five functions built in to the language. They are eval, parseInt, parseFloat, escape, and unescape.


1 Answers

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

like image 83
talemyn Avatar answered Sep 30 '22 19:09

talemyn