Get the Name of an object’s class in JXA?

Anyone know how to determine the name of the Foundation or JXA class corresponding to an object?

// How to get "Path" from:
Path("/Library")
// typeof returns object

// How get "NSDictionary" from:
$.NSDictionary.alloc.init
// typeof returns function

I understand why typeof returns these values. I also know that if I am just trying to test whether a value is an instance of some class I can use instanceof. But I am wondering whether there is some kind of Foundation function, or special JXA function, that will return the actual class, or its name.

I tend to prefer functional composition and static typing, so not something that I do much, but in principle, for JS objects that have a named constructor on their prototype chain, you can test with instanceof. For reading ObjC objects through the ObjC bridge, it may prove worth researching and experimenting with the use of $.NSStringFromClass

(function() {
    'use strict';

    // How to get "Path" from:
   var p =  Path("/Library")
    // typeof returns object
    
    // How get "NSDictionary" from:
    var d = $.NSDictionary.alloc.init
    // typeof returns function
    
    
    return {
        test: p instanceof Path,
    
        stringFromClass: $.NSStringFromClass($.NSDictionary.alloc).js
    };
})();

Apple's JS Automation object also has an Automation.getDisplayString(Object) method which might prove useful in some contexts.

You can also, of course, directly inspect the prototype chain with Object.getPrototypeOf(). Sometimes it will include a named constructor:

Object.getPrototypeOf(3).constructor.name
// "Number"

Sometimes not:

Object.getPrototypeOf(Path("/Library"))
// {"constructor":[function anonymous], "toString":[function anonymous]}

The problem is that JS really only has one type (Object) plus a mechanism for prototype specialisations. Not a bad scheme, in some ways, but this is one of its limitations.

(Also worth checking, in the Mozilla documentation, for various specalised predicate functions like .isArray(), .isInteger() etc)

I recommend: http://www.purescript.org/

PS I think I have posted this kind of code before, but FWIW you can inspect the methods of the JS Automation object by running something like:

(function () {
    'use strict';

    var lstSeen = ['Automation'];

    var keyTree = function keyTree(o, strIndent) {
        var indent = strIndent || '',
            ks = Object.getOwnPropertyNames(o)
            .filter(function (k) {
                return ['name', 'prototype', '__private__'].indexOf(k) === -1 &&
                    lstSeen.indexOf(k) === -1 ? (lstSeen.push(k), true) : false;
            })
            .sort();

        return ks.length ? ks.map(function (k) {
                return indent + k + '\n' + keyTree(o[k], indent + '    ');
            })
            .join('') : '';
    };

    return 'Automation\n' + keyTree(Automation, '    ');
})();
Automation
    Application
        currentApplication
    Library
    ObjC
        $
        Ref
            equals
        bindFunction
        block
        castObjectToRef
        castRefToObject
        deepUnwrap
        dict
        import
        interactWithUser
        registerSubclass
        super
        unwrap
        wrap
    ObjectSpecifier
    Path
    Progress
    delay
    getDisplayString
    initializeGlobalObject
    log

and if you look at Object.getOwnPropertyNames() above, it may suggest ways of testing an object at runtime by seeing whether or not it has a particular method or property.

The full range of tools at your disposal can be listed with:

(function() {
    'use strict';
    
    return Object.getOwnPropertyNames(Object);
    
})();

which yields:

[
  "getPrototypeOf",
  "setPrototypeOf",
  "getOwnPropertyDescriptor",
  "getOwnPropertyDescriptors",
  "getOwnPropertyNames",
  "getOwnPropertySymbols",
  "keys",
  "defineProperty",
  "defineProperties",
  "create",
  "seal",
  "freeze",
  "preventExtensions",
  "isSealed",
  "isFrozen",
  "isExtensible",
  "is",
  "assign",
  "name",
  "prototype",
  "length"
]