Why a number isn’t instance of Number with typeof and instanceof? Code Answer

Hello Developer, Hope you guys are doing great. Today at Tutorial Guruji Official website, we are sharing the answer of Why a number isn’t instance of Number with typeof and instanceof? without wasting too much if your time.

The question is published on by Tutorial Guruji team.

I need to take all elements of given type from an array, like this [{ a: 'a' }, 4, /a-z/, 6, [1, 2, 3], i=>i], and when I provide type Number as argument to ofType(type) it returns [ ] :

Array.prototype.ofType = function (type) {
    let newArr = []; 
    this.forEach(i => i instanceof type ? newArr.push(i) : newArr );
    return newArr
}

in other cases , like [{ a: 'a' }, 4, /a-z/, 6, [1, 2, 3], i=>i].ofType(RegExp) it works correctly.

Answer

JavaScript has number primitives and Number objects. A number primitive isn’t instanceof anything because it isn’t an object, and only objects are “instances” of something (“instance” being a term of art from object oriented programming); so instanceof is not useful for primitives.

That’s where typeof comes in. The result of typeof for primitive numbers is "number".

Since instanceof expects a constructor function as the right hand operand, you could have your ofType function branch based on whether it gets a function or a string, using instanceof if it’s a function and typeof if it’s a string. Using your forEach loop:

Array.prototype.ofType = function (type) {
    let newArr = []; 
    if (typeof type === "string") {
        this.forEach(i => typeof i === type ? newArr.push(i) : newArr );
    } else {
        this.forEach(i => i instanceof type ? newArr.push(i) : newArr );
    }
    return newArr;
};

But I wouldn’t use forEach for this, I’d use filter:

Array.prototype.ofType = function (type) {
    let newArr;
    if (typeof type === "string") {
        newArr = this.filter(i => typeof i === type);
    } else {
        newArr = this.filter(i => i instanceof type);
    }
    return newArr;
};

Also, I strongly recommend not adding enumerable properties to Array.prototype, it breaks code that incorrectly uses for-in loops on arrays. Use Object.defineProperty instead:

Object.defineProperty(Array.prototype, "ofType", {
    value(type) {
        let newArr;
        if (typeof type === "string") {
            newArr = this.filter(i => typeof i === type);
        } else {
            newArr = this.filter(i => i instanceof type);
        }
        return newArr;
    },
    writable: true,
    configurable: true,
    enumerable: false // This is the default, so you could leave it off
});

Live Example:

Object.defineProperty(Array.prototype, "ofType", {
    value(type) {
        let newArr;
        if (typeof type === "string") {
            newArr = this.filter(i => typeof i === type);
        } else {
            newArr = this.filter(i => i instanceof type);
        }
        return newArr;
    },
    writable: true,
    configurable: true,
    enumerable: false // This is the default, so you could leave it off
});

console.log([1, "2", 3, "4"].ofType("number"));

console.log([new Date, "2", new Date, "4"].ofType(Date));
We are here to answer your question about Why a number isn’t instance of Number with typeof and instanceof? - If you find the proper solution, please don't forgot to share this with your team members.

Related Posts

Tutorial Guruji