0

I would like to analyse the classes of three.js library. I have a function, that can find out, if the given class relaying on another class or not.

function getParent (className) {
    var parent = null;
    var object = new THREE[className]();

    for (var a in THREE) {
        if (typeof THREE[a] === "function" && object instanceof THREE[a] && a !== className) {
            parent = a;

            break
        }
    }
    return(parent)
}

And I also would like to have a function that returns 2 arrays. One with properties and one with methods. When iterating over "object", I can determine what kind of the member is, but how can i check that, it is not inherited? If parent is exist and I store a reference of it, negating the result of parentObject.hasOwnProperty does not work.

for (var member in object) {
    if (typeof object[member] === "function") {
        if (!parentObject.hasOwnProperty(member)) {
            methods.push(member)
        }
    }
    else {
        //...
    }
}
Łukasz
  • 2,131
  • 1
  • 13
  • 28
  • I'm confused why you are trying to do this and what you will achieve from it? JavaScript uses prototyping so it does not have **classes** or **inheritance** like other object-oriented languages – neelsg Jun 09 '14 at 13:08
  • I am binding this library to a strongly typed functional language, and currently there are classes that are poorly documented, so I have to find a way to analyse them, because I do not want to spend a bunch of hours with searching in the soure code. – Sándor Rakonczai Jun 09 '14 at 13:13
  • @neelsg: prototyping *is* a form of inheritance. And even though JS does not [yet] have a `class` keyword, you can (and do) use the pattern. – Bergi Jun 09 '14 at 14:33

2 Answers2

0

hasOwnProperty does not check through the prototype chain, so if it returns true you know that the property was not inherited. You don't need to check the parent object members.

if (object.hasOwnProperty(member))
    methods.push(member)
else
    ...

For more details - Object.prototype.hasOwnProperty()

Assaf Shemesh
  • 2,078
  • 2
  • 18
  • 19
0

I hope you have understood how classes work in JavaScript and how inheritance is done for them.

for (var a in THREE) {
   if (typeof THREE[a] === "function" && object instanceof THREE[a] && a !== className) {
       parent = a;

That does not work for multi-level inheritance. Better use something like

function getParent (className) {
    var proto = THREE[className].prototype,
        parproto = Object.getPrototypeOf(proto);

    for (var a in THREE)
        if (typeof THREE[a] === "function" && THREE[a].prototype === parproto)
            return a;
    return null;
}

But notice that this only detects prototypical inheritance, no such things like mixin inheritance. Since prototypical inheritance is done using the standard pattern in Three.js, you might as well just search the code

I can determine what kind of the member is, but how can i check that, it is not inherited? If parent is exist and I store a reference of it, negating the result of parentObject.hasOwnProperty does not work.

I don't know what parentObject is in your case, but especially for methods it might be likely that an instance does inherit the method from its prototype, i.e. does not have it as an own property.

You better do something like this:

function describeProperties(className) {
    try {
        var o = new THREE[className](), // do you know appropriate arguments?
            p = Object.getPrototypeOf(o);
    } catch(e) { // probably constructor call was not successful
        o = p = THREE[className].prototype;
    }
    var props = {};
    for (var prop in o) {
        var desc = [];
        desc.push( (typeof o[prop] == "function") ? "method" : "value");
        if (!(prop in p)) // does not appear on the prototype
            desc.push("instance-specific") // so was added in constructor
        if (o !== p && o.hasOwnProperty(prop) && prop in p)
            desc.push("defaulted");
        if (prop in Object.getPrototypeOf(p)) {
            desc.push("inherited") // from parent class
            if (p.hasOwnProperty(prop)) // but also in own prototype
                desc.push("overwritten");
        }
        props[prop] = desc.join(" ");
    }
    return props;
}
Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375