1

I have the JavaScript snippet below. Simply put, what am trying to achieve is; A way to check if a parameter passed to a function is an instance of some predetermined classes. I know I can use

if(obj instanceof className){ /* do stuff * / } else{ /* other things */ }
statements but it would be bulky code, especially if I have a bunch of classes to test against. To cut the story short, how can I achieve what am trying to do with the code below? Thanks all.

class A {
    constructor(name) {
        this._name = name;
    }
}
class B {
    constructor(name) {
        this._name = name;
    }
}
class C {
    constructor(name) {
        this._name = name;
    }
}
let allTemplates = ['A', 'B', 'C', 'Object']; //available classes

let a = new A('A class');
let b = new B('B class');
let c = new C('C class');

function seekTemplateOf(obj) {
    /**find if @arg obj is an instance of any
     ** of the classes above or just an object
     **@return string "class that obj is instance of"
     **/
    return allTemplates.find(function(template) {
        return obj instanceof window[template];
        /*Thought that ^^ could do the trick?*/
    });
}
console.log(seekTemplateOf(a));
/*"^^ Uncaught TypeError: Right-hand side of 'instanceof' is not an object"*/

7
  • 2
    Why a string? Why not allTemplates = [A, B, C, Object]? Commented Feb 5, 2018 at 16:00
  • Sort of sounds to me like you want the new.target syntax. You should ask about the actual problem instead of your solution. Commented Feb 5, 2018 at 16:04
  • related: Create object from string in JavasScript ECMAScript 6 Commented Feb 5, 2018 at 16:08
  • 1
    @skinny pete dont think so. Commented Feb 5, 2018 at 16:08
  • @JonasW.: Why? This question reads like it's trying to solve a specific problem without actual describing that problem. It could very well be that or it could be something else. Point is to describe what is actually needed, because what they perceive to be a good solution often isn't. Commented Feb 5, 2018 at 16:10

2 Answers 2

1

You could use an object for the templates and check againt the given objects.

class A { constructor(name) { this._name=name; } }
class B { constructor(name) { this._name=name; } }
class C { constructor(name) { this._name=name; } }

let allTemplates = { A, B, C, Object };

let a = new A('A class');
let b = new B('B class');
let c = new C('C class');

function seekTemplateOf(obj) {
    return Object.keys(allTemplates).find(template => obj instanceof allTemplates[template]);
}

console.log(seekTemplateOf(a));

Sign up to request clarification or add additional context in comments.

Comments

1

Change your strings to references:

let allTemplates = [A, B, C, Object];

Then check if the objects constructor is equal to that:

const obj = new A;
const objClass = allTemplates.find(c => obj.constructor === c);

Alternatively ( if some prototype hacker forgot to set constructor) you might get the definite prototype:

const obj = new A;
const objClass = allTemplates.find(c => Object.getPrototypeOf(obj) === c.prototype);

Or you might simply use instanceof then:

const obj = new A;
const objClass = allTemplates.find(c =>  obj instanceof c);

2 Comments

Not sure why you changed the proper instanceof to .constructor ===?
@bergi dont know either ;)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.