517

In my particular case:

callback instanceof Function

or

typeof callback == "function"

does it even matter, what's the difference?

Additional Resource:

JavaScript-Garden typeof vs instanceof

naXa stands with Ukraine
  • 35,493
  • 19
  • 190
  • 259
farinspace
  • 8,422
  • 6
  • 33
  • 46
  • 2
    I found my [answer here](http://stackoverflow.com/a/23317160/1815624) as a easy to use solution – CrandellWS Apr 26 '14 at 22:26
  • 1
    There is another way to check type using `Object.prototype.toString` http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring] – rab Jun 28 '15 at 15:04
  • 1
    just use `.constructor` property instead. – Muhammad Umer Aug 02 '15 at 17:16
  • If you wonder about **performance**, see my [answer below](http://stackoverflow.com/a/32272154/797243). *typeof* is faster where both are applicable (namely objects). – Martin Peter Aug 28 '15 at 13:29

26 Answers26

684

Use instanceof for custom types:

var ClassFirst = function () {};
var ClassSecond = function () {};
var instance = new ClassFirst();
typeof instance; // object
typeof instance == 'ClassFirst'; // false
instance instanceof Object; // true
instance instanceof ClassFirst; // true
instance instanceof ClassSecond; // false 

Use typeof for simple built in types:

'example string' instanceof String; // false
typeof 'example string' == 'string'; // true

'example string' instanceof Object; // false
typeof 'example string' == 'object'; // false

true instanceof Boolean; // false
typeof true == 'boolean'; // true

99.99 instanceof Number; // false
typeof 99.99 == 'number'; // true

function() {} instanceof Function; // true
typeof function() {} == 'function'; // true

Use instanceof for complex built in types:

/regularexpression/ instanceof RegExp; // true
typeof /regularexpression/; // object

[] instanceof Array; // true
typeof []; //object

{} instanceof Object; // true
typeof {}; // object

And the last one is a little bit tricky:

typeof null; // object
Szymon Wygnański
  • 10,642
  • 6
  • 31
  • 44
  • 16
    This answer makes it clear why instaceof should **not** be used for primitive types. It's pretty obvious you don't have an option when it comes to custom types, as well as the benefit for 'object' types. But what makes functions lumped in with "simple built-in types"? I find it odd how a function behaves like an object, yet it's type is 'function' making the use of 'typeof' feasible. Why would you discourage instanceof for it, though? – Assimilater Jul 29 '14 at 02:06
  • I'm not sure if there is an adequate answer @Assimilater. Fact is that `typeof` is consistent to tell you whether something is a function or not. However, I can't think of any examples where `instanceof` would give you the wrong answer. – froginvasion Jul 30 '14 at 14:16
  • 4
    @Assimilater you could use instanceof with functions as well however I consider these 3 rules being very simple to remember and yes, functions are an exception:) – Szymon Wygnański May 03 '15 at 05:19
  • 3
    another tricky part -> 'example string' instanceof String; // false but new String('example string') instanceof String; //true – Luke Nov 13 '15 at 08:57
  • 2
    @Luke generally a bad idea to use "new String" like this. that creates a "string object" rather than a string primitive. see section here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String – Colin D Jan 29 '16 at 09:43
  • 6
    `Use instanceof for complex built in types` - this is still prone to error. Better to use ES5 `Array.isArray()` et al. or the recommended shims. – OrangeDog May 04 '16 at 11:27
  • You're mostly right, but for example string can be created at at least two ways: ```const a = 'string'; const b = new String('string');``` Checking if `b instanceof` String will yield true typeof will work string literal, instanceof if created with constructor – Chris Panayotoff Jan 22 '20 at 21:00
  • 1
    I'm still confused. Why is `'example string' instanceof String` false? How is it not an instance of a string? – David Klempfner May 17 '21 at 11:48
  • Never mind. This sentence says it all: "instanceof of returns true if an object is created from a given constructor and false otherwise." - https://levelup.gitconnected.com/comparing-the-javascript-typeof-and-instanceof-operators-8844f23633a – David Klempfner May 17 '21 at 12:00
  • @DavidKlempfner this is because a string created this way: 'example string' is not an object of type String but a primitive value that is string. If you would want to created the string object then you have to use `new String('example string')` explicitly (however don't do it ever). – Szymon Wygnański May 18 '21 at 12:06
122

Both are similar in functionality because they both return type information, however I personally prefer instanceof because it's comparing actual types rather than strings. Type comparison is less prone to human error, and it's technically faster since it's comparing pointers in memory rather than doing whole string comparisons.

Beta
  • 96,650
  • 16
  • 149
  • 150
Soviut
  • 88,194
  • 49
  • 192
  • 260
  • On other hand, I think it would have weird problems in multi-window (iframe anyone) setups. – alamar May 22 '09 at 19:29
  • In that case you'd have to deal with proper namespacing and domains. – Soviut May 22 '09 at 19:32
  • 9
    there are some situations where instanceof will not work as expected and typeof works well ... https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Operators/Special_Operators/Instanceof_Operator#Description – farinspace May 22 '09 at 19:37
  • 58
    instanceof works with objects in the same window. If you use iframe/frame or popup-windows each (i)frame/window have their own "function" object and instanceof will fail if you try to compare an object from another (i)frame/window. typeof will work in all cases since it returns the string "function". – some May 23 '09 at 16:56
  • 14
    http://jsperf.com/typeof-function-vs-instanceof/3 I tried on Chrome and FF3.X, "typeof" approach is faster. – Morgan Cheng Jun 14 '11 at 03:03
  • 12
    This is just false. They are not identical. They do not both work in all of the same situations, especially across different JavaScript VMs and browsers. – Justin Force Nov 22 '11 at 00:48
  • I meant their functionality is similar in that they both return type information, but one returns it as an type definition and the other returns a string. – Soviut Nov 24 '11 at 07:34
  • 9
    Your answer says "both are essentially identical in terms of functionality." Respectfully, this is patently false. As outlined and explained in my answer, neither option works in every situation—especially across browsers. The better approach is to use both with an || operator. – Justin Force Nov 29 '11 at 20:27
  • The original question mentioned nothing about browsers; who knows, maybe the OP is writing script in Node. – Soviut Apr 21 '12 at 17:24
  • @soviut—if you include ECMAScript implementations in general, then their similarity is even more marginal. They are very different tests. If the intention is to determine is something is a callable native function, I would use `typeof` every time. – RobG May 24 '12 at 02:18
  • 2
    Many implementations of JS (I know that V8 does, not sure about other implementations) have `typeof something === "type"` special cased, so there is no real string comparison. – Konrad Borowski Jul 20 '13 at 07:37
  • Not quite. The `instanceof` operator travels up the prototype chain, looking for the constructor's prototype [http://mdn.io/instanceof]. So, it allows for checking if something's an instance of a "subclass." – omninonsense Dec 20 '13 at 22:56
  • This answer is incorrect, see the answer I added, when an object is created like this: `Object.create(Function)`, your code will break, if you use `instanceof` instead of `typeof`. – vitaly-t Jul 19 '16 at 23:41
  • @some is right that you need a rationale. The framing issue mentioned here is one. Another is that you can break `instanceof` by messing with the `contructor` property. See the 2ality post "[What object is not an instance of Object?](http://2ality.com/2012/08/instanceof-object.html)" And because javascript turns us into [gelatinous goo](https://news.ycombinator.com/item?id=13942674), we do things like that. – harpo Mar 28 '17 at 03:05
111

A good reason to use typeof is if the variable may be undefined.

alert(typeof undefinedVariable); // alerts the string "undefined"
alert(undefinedVariable instanceof Object); // throws an exception

A good reason to use instanceof is if the variable may be null.

var myNullVar = null;
alert(typeof myNullVar ); // alerts the string "object"
alert(myNullVar  instanceof Object); // alerts "false"

So really in my opinion it would depend on what type of possible data you are checking.

Kenneth J
  • 4,846
  • 11
  • 39
  • 56
  • 12
    +1 also note that `instanceof` cannot compare to primitive types, typeof can. – Tino Mar 18 '11 at 11:42
  • 3
    In Chrome 29.0.1541.0 dev `undefined instanceof Object` returns false, and doesn't throw an exception. I don't know how recent that change is, but it makes `instanceof` more appealing. – Cypress Frankenfeld Jun 26 '13 at 16:01
  • 7
    `undefined instanceof Object` doesn't throw an exception because, eh, `undefined` is defined. The constant exists in the namespace. When a variable does not exist (due to typo for instance), instanceof will throw an exception. Using typeof on an non-existing variable yields 'undefined' on the other hand. – cleong Mar 28 '15 at 13:06
51

To make things clear, you need to know two facts:

  1. The instanceof operator tests whether the prototype property of a constructor appears anywhere in the prototypes chain of an object. In most cases this mean that the object was created by using this constructor or on of its descendant. But also prototype may be set explicitly by Object.setPrototypeOf() method (ECMAScript 2015) or by the __proto__ property (old browsers, deprecated). Changing the prototype of an object is not recommended though, because of performance issues.

Thus instanceof is applicable only to objects. In most cases you aren't using constructors to create strings or numbers. You can. But you almost never do.

Also instanceof can't check, exactly which constructor was used to create the object, but will return true, even if object is derived from class which being checked. In most cases this is the desired behavior, but sometimes it's not. So you need to keep that mind.

Another problem is that different scopes have different execution environments. This means that they have different built-ins (different global object, different constructors, etc.). This may result in unexpected results.

For example, [] instanceof window.frames[0].Array will return false, because Array.prototype !== window.frames[0].Array and arrays inherit from the former.
Also, it cannot be used on undefined value, because it don't have a prototype.

  1. The typeof operator tests whether value belong to one of six basic types: "number", "string", "boolean", "object", "function" or "undefined". Where the string "object" belong all objects (except functions, which are objects, but have its own value in typeof operator), and also "null" value and arrays (for "null" it's a bug, but this bug is so old, so it's become a standard). It doesn't rely on constructors and can be used even if value is undefined. But it's doesn't give any details about objects. So if you needed it, go to instanceof.

Now let's talk about one tricky thing. What if you use constructor to create a primitive type?

let num = new Number(5);
console.log(num instanceof Number); // print true
console.log(typeof num); // print object
num++; //num is object right now but still can be handled as number
//and after that:
console.log(num instanceof Number); // print false
console.log(typeof num); // print number

Seems like magic. But it is not. It's so-called boxing (wrapping primitive value by object) and unboxing (extracting wrapped primitive value from object). Such kind of code seems to be "a bit" fragile. Of course you can just avoid creating primitive type with constructors. But there is another possible situation, when boxing may hit you. When you use Function.call() or Function.apply() on a primitive type.

function test(){
  console.log(typeof this);
} 
test.apply(5);

To avoiding this you can use strict mode:

function test(){
  'use strict';
  console.log(typeof this);
} 
test.apply(5);

upd: Since ECMAScript 2015, there is one more type called Symbol, which has its own typeof == "symbol".

console.log(typeof Symbol());
// expected output: "symbol"

You can read about it on MDN: (Symbol, typeof).

Vladimir Liubimov
  • 964
  • 1
  • 11
  • 16
  • 3
    `if an object is created by a given constructor` This is incorrect. `o instanceof C` will return true if o inherits from C.prototype. You have mentioned something about this later in your answer but it is not very clear. – oyenamit Mar 13 '18 at 19:46
  • 1
    incorrect...from the book : " https://github.com/getify/You-Dont-Know-JS" a instanceof Foo; // true The instanceof operator takes a plain object as its left-hand operand and a function as its right-hand operand. The question instanceof answers is: in the entire [[Prototype]] chain of a, does the object arbitrarily pointed to by Foo.prototype ever appear? – Deen John Apr 25 '18 at 11:36
  • 1
    I've edit the answer, to be more correct. Thank for your comments. – Vladimir Liubimov Aug 07 '18 at 10:05
  • Also, explanation of boxing/unboxing issue was added. – Vladimir Liubimov Aug 07 '18 at 10:06
17

I've discovered some really interesting (read as "horrible") behavior in Safari 5 and Internet Explorer 9. I was using this with great success in Chrome and Firefox.

if (typeof this === 'string') {
    doStuffWith(this);
}

Then I test in IE9, and it doesn't work at all. Big surprise. But in Safari, it's intermittent! So I start debugging, and I find that Internet Explorer is always returning false. But the weirdest thing is that Safari seems to be doing some kind of optimization in its JavaScript VM where it is true the first time, but false every time you hit reload!

My brain almost exploded.

So now I've settled on this:

if (this instanceof String || typeof this === 'string')
    doStuffWith(this.toString());
}

And now everything works great. Note that you can call "a string".toString() and it just returns a copy of the string, i.e.

"a string".toString() === new String("a string").toString(); // true

So I'll be using both from now on.

Justin Force
  • 6,203
  • 5
  • 29
  • 39
9

Other Significant practical differences:

// Boolean

var str3 = true ;

alert(str3);

alert(str3 instanceof Boolean);  // false: expect true  

alert(typeof str3 == "boolean" ); // true

// Number

var str4 = 100 ;

alert(str4);

alert(str4 instanceof Number);  // false: expect true   

alert(typeof str4 == "number" ); // true
kongaraju
  • 9,344
  • 11
  • 55
  • 78
9

instanceof also works when callback is a subtype of Function, I think

newacct
  • 119,665
  • 29
  • 163
  • 224
8

typeof: Per the MDN docmentation, typeof is a unary operator that returns a string indicating the type of the unevaluated operand.

In the case of string primitaves and string objects, typeof returns the following:

const a = "I'm a string primitive";
const b = new String("I'm a String Object");

typeof a; --> returns 'string'
typeof b; --> returns 'object'

instanceof: is a binary operator, accepting an object and a constructor. It returns a boolean indicating whether or not the object has the given constructor in its prototype chain.

When applied to the string instances above, and compared to String, it behaves as follows:

const a = "I'm a string primitive";
const b = new String("I'm a String Object");

a instanceof String; --> returns false
b instanceof String; --> returns true

Reference: https://bambielli.com/til/2017-06-18-typeof-vs-instanceof/

Sandeep Amarnath
  • 5,463
  • 3
  • 33
  • 43
5

instanceof in Javascript can be flaky - I believe major frameworks try to avoid its use. Different windows is one of the ways in which it can break - I believe class hierarchies can confuse it as well.

There are better ways for testing whether an object is a certain built-in type (which is usually what you want). Create utility functions and use them:

function isFunction(obj) {
  return typeof(obj) == "function";
}
function isArray(obj) {
  return typeof(obj) == "object" 
      && typeof(obj.length) == "number" 
      && isFunction(obj.push);
}

And so on.

levik
  • 114,835
  • 27
  • 73
  • 90
  • 3
    In case you didn't know: typeof don't need parenthesis since it is a keyword and not a function. And IMHO you should use === instead of ==. – some May 23 '09 at 17:05
  • 6
    @some You are right about typeof but in this case there is no need for ===, it is only needed when the value being compared could equal without having the same type. Here, it can't. – Nicole Mar 04 '10 at 19:08
  • @some does typeof ever return something other than a string? – Kenneth J May 21 '10 at 16:15
  • So isArray would be wrong for, say, a stack object with a push method and a numeric length attribute. Under what circumstances would (instanceof Array) be wrong? – Chris Noe Nov 08 '10 at 23:43
  • @ChrisNoe The problem arises with objects shared between multiple frames: https://groups.google.com/forum/#!msg/comp.lang.javascript/XTWYCOwC96I/70rNoQ3L-xoJ –  Dec 08 '13 at 20:11
  • You should be using the EcmaScript 5 [Array.isArray](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray) function instead of trying to create your own. – Alex Henrie Feb 20 '15 at 20:21
4

When checking for a function, one must always use typeof.

Here's the difference:

var f = Object.create(Function);

console.log(f instanceof Function); //=> true
console.log(typeof f === 'function'); //=> false

f(); // throws TypeError: f is not a function

This is why one must never use instanceof to check for a function.

vitaly-t
  • 24,279
  • 15
  • 116
  • 138
  • I can argue that it is `typeof` that is wrong -- `f` is all of the following: an `Object` (an object) and a `Function` (a function). Except for me it makes more sense to use `instanceof` because knowing that it is a function I know it is an object as well, since all functions are objects in ECMAScript. The converse is not true -- knowing from `typeof` that `f` is indeed an `object` I have no idea that it is also a function. – Armen Michaeli May 28 '18 at 12:39
  • @amn For me, it's a *broken* instance of Function. It gets attributes like `length`, `name` and `call` from Function, but all of them are defunct. What's worse, it can't be called and the `TypeError` says it: `f is not a function`. – maaartinus May 15 '20 at 20:48
3

Performance

typeof is faster than instanceof in situations where both are applicable.

Depending on your engine, the performance difference in favor of typeof could be around 20%. (Your mileage may vary)

Here is a benchmark testing for Array:

var subject = new Array();
var iterations = 10000000;

var goBenchmark = function(callback, iterations) {
    var start = Date.now();
    for (i=0; i < iterations; i++) { var foo = callback(); }
    var end = Date.now();
    var seconds = parseFloat((end-start)/1000).toFixed(2);
    console.log(callback.name+" took: "+ seconds +" seconds.");
    return seconds;
}

// Testing instanceof
var iot = goBenchmark(function instanceofTest(){
     (subject instanceof Array);
}, iterations);

// Testing typeof
var tot = goBenchmark(function typeofTest(){
     (typeof subject == "object");
}, iterations);

var r = new Array(iot,tot).sort();
console.log("Performance ratio is: "+ parseFloat(r[1]/r[0]).toFixed(3));

Result

instanceofTest took: 9.98 seconds.
typeofTest took: 8.33 seconds.
Performance ratio is: 1.198
Martin Peter
  • 3,565
  • 2
  • 23
  • 26
  • 1
    typeof subject == "array" should return false. typeof subject is "object". – Shardul Feb 05 '17 at 01:43
  • how come typeof is faster? is Javascript interning the literal strings? – Gregory Magarshak Apr 30 '17 at 18:25
  • The reason is: `instanceof` _always_ follows object's prototype chain, so performance penalty will depend on how far in prototype chain is the class, `instanceof` is tested against. So for short inheritance chain the penalty will be lower (like, `[] instanceof Array`, `{} instanceof Object`), and for long - bigger. So, if both `obj instanceof SomeClass` and `typeof obj !== 'string'` means the same from the perspective of some your hypothetical code (f.e. if you just making a test in `if`, and not `switch`-ing through multiple classes etc.), then you'd better pick second one, performance-wise, – ankhzet Jun 13 '17 at 08:37
3

This is just complementary knowledge to all the other explanations here - I am not suggesting to use .constructor everywhere.

TL;DR: In situations where typeof is not an option, and when you know that you do not care about the prototype chain, Object.prototype.constructor can be a viable or even better alternative than instanceof:

x instanceof Y
x.constructor === Y

It's been in the standard since 1.1, so no worries about backwards compatibility.

Muhammad Umer briefly mentioned this in a comment somewhere here too. It works on everything with a prototype - so everything not null or undefined:

// (null).constructor;      // TypeError: null has no properties
// (undefined).constructor; // TypeError: undefined has no properties

(1).constructor;                 // function Number
''.constructor;                  // function String
([]).constructor;                // function Array
(new Uint8Array(0)).constructor; // function Uint8Array
false.constructor;               // function Boolean()
true.constructor;                // function Boolean()

(Symbol('foo')).constructor;     // function Symbol()
// Symbols work, just remember that this is not an actual constructor:
// new Symbol('foo'); //TypeError: Symbol is not a constructor

Array.prototype === window.frames.Array;               // false
Array.constructor === window.frames.Array.constructor; // true

Furthermore, depending on your use case it can be a lot faster than instanceof (the reason likely being that it doesn't have to check the entire prototype chain). In my case I needed a fast way to check if a value is a typed array:

function isTypedArrayConstructor(obj) {
  switch (obj && obj.constructor){
    case Uint8Array:
    case Float32Array:
    case Uint16Array:
    case Uint32Array:
    case Int32Array:
    case Float64Array:
    case Int8Array:
    case Uint8ClampedArray:
    case Int16Array:
      return true;
    default:
      return false;
  }
}

function isTypedArrayInstanceOf(obj) {
  return obj instanceof Uint8Array ||
    obj instanceof Float32Array ||
    obj instanceof Uint16Array ||
    obj instanceof Uint32Array ||
    obj instanceof Int32Array ||
    obj instanceof Float64Array ||
    obj instanceof Int8Array ||
    obj instanceof Uint8ClampedArray ||
    obj instanceof Int16Array;
}

https://run.perf.zone/view/isTypedArray-constructor-vs-instanceof-1519140393812

And the results:

Chrome 64.0.3282.167 (64-bit, Windows)

Typed Array instanceof vs constructor - 1.5x faster in Chrome 64.0.3282.167 (64-bit, Windows)

Firefox 59.0b10 (64-bit, Windows)

Typed Array instanceof vs constructor - 30x faster in Firefox 59.0b10 (64-bit, Windows)

Out of curiousity, I did a quick toy benchmark against typeof; surprisingly it doesn't perform much worse, and it seems even a bit faster in Chrome:

let s = 0,
    n = 0;

function typeofSwitch(t) {
    switch (typeof t) {
        case "string":
            return ++s;
        case "number":
            return ++n;
        default:
            return 0;
    }
}

// note: no test for null or undefined here
function constructorSwitch(t) {
    switch (t.constructor) {
        case String:
            return ++s;
        case Number:
            return ++n;
        default:
            return 0;
    }
}

let vals = [];
for (let i = 0; i < 1000000; i++) {
    vals.push(Math.random() <= 0.5 ? 0 : 'A');
}

https://run.perf.zone/view/typeof-vs-constructor-string-or-number-1519142623570

NOTE: Order in which functions are listed switches between images!

Chrome 64.0.3282.167 (64-bit, Windows)

String/Number typeof vs constructor - 1.26x faster in Chrome 64.0.3282.167 (64-bit, Windows)

Firefox 59.0b10 (64-bit, Windows)

NOTE: Order in which functions are listed switches between images!

String/Number typeof vs constructor - 0.78x slower in Firefox 59.0b10 (64-bit, Windows)

Job
  • 856
  • 10
  • 13
3

I would recommend using prototype's callback.isFunction().

They've figured out the difference and you can count on their reason.

I guess other JS frameworks have such things, too.

instanceOf wouldn't work on functions defined in other windows, I believe. Their Function is different than your window.Function.

BenMorel
  • 34,448
  • 50
  • 182
  • 322
alamar
  • 18,729
  • 4
  • 64
  • 97
3

instanceof will not work for primitives eg "foo" instanceof String will return false whereas typeof "foo" == "string" will return true.

On the other hand typeof will probably not do what you want when it comes to custom objects (or classes, whatever you want to call them). For example:

function Dog() {}
var obj = new Dog;
typeof obj == 'Dog' // false, typeof obj is actually "object"
obj instanceof Dog  // true, what we want in this case

It just so happens that functions are both 'function' primitives and instances of 'Function', which is a bit of an oddity given that it doesn't work like that for other primitive types eg.

(typeof function(){} == 'function') == (function(){} instanceof Function)

but

(typeof 'foo' == 'string') != ('foo' instanceof String)
Omnimike
  • 1,435
  • 2
  • 15
  • 12
2

Significant practical difference:

var str = 'hello word';

str instanceof String   // false

typeof str === 'string' // true

Don't ask me why.

Barney
  • 16,181
  • 5
  • 62
  • 76
  • 11
    Because here `str` is a string primitive, not a string object. The same goes for number primitives and boolean primitives, they aren't instances of their "constructed" counterparts, the String, Number and Boolean objects. JavaScript automatically converts these three primitives to objects when required (such as utilizing a method on the object's prototype chain). On the flip side of your practical difference, *instanceof* is better for checking for arrays since `typeof [] == "object" // true`. – Andy E Oct 03 '10 at 19:20
2

no need to overwhelm with ton of above examples, just keep in mind two points of view:

  1. typeof var; is an unary operator will return the original type or root type of var. so that it will return primitive types(string, number, bigint, boolean, undefined, and symbol) or object type.

  2. in case of higher-level object, like built-in objects (String, Number, Boolean, Array..) or complex or custom objects, all of them is object root type, but instance type built base on them is vary(like OOP class inheritance concept), here a instanceof A - a binary operator - will help you, it will go through the prototype chain to check whether constructor of the right operand(A) appears or not.

so whenever you want to check "root type" or work with primitive variable - use "typeof", otherwise using "instanceof".

null is a special case,which is seemingly primitive, but indeed is a special case for object. Using a === null to check null instead.

on the other hand, function is also a special case, which is built-in object but typeof return function

as you can see instanceof must go through the prototype chain meanwhile typeof just check the root type one time so it's easy to understand why typeof is faster than instanceof

Lam Phan
  • 3,405
  • 2
  • 9
  • 20
1

var newObj =  new Object;//instance of Object
var newProp = "I'm xgqfrms!" //define property
var newFunc = function(name){//define function 
 var hello ="hello, "+ name +"!";
 return hello;
}
newObj.info = newProp;// add property
newObj.func = newFunc;// add function

console.log(newObj.info);// call function
// I'm xgqfrms!
console.log(newObj.func("ET"));// call function
// hello, ET!

console.log(newObj instanceof Object);
//true
console.log(typeof(newObj));
//"object"
xgqfrms
  • 10,077
  • 1
  • 69
  • 68
1

After reading this thread, I came out with a self conclusion and created a quick reference chart, tested in Chrome.

Preferred cells (in bold) can be picked up, involving a simpler usecase.

TYPES self typeof instanceof constructor
null null object
undefined undefined undefined
array [] Array.isArray([]) object Array
bool boolean Boolean
number number Number
string string String
symbol symbol Symbol
function function Function Function
class function Function Function
object {} object Object Object
RegExp /abc/ object RegExp RegExp
new Array() object Array Array
new Boolean() object Boolean Boolean
new Number() object Number Number
new String() object String String
new myFunction() object myFunction myFunction
new myClass() object myClass myClass

Thumb Rule:

  • For checking primitive types use typeof
  • Null can be checked as myvar === null
  • Undefined can be checked as myvar === undefined
  • Array can be checked using Array.isArray([])
  • Object can be check using myvar instanceof Object
  • Constructor column can be utilized in a similar fashion as ({}).constructor or ([]).constructor

I admit, the guide is not fully correct, as Creating objects or classes in a different way can result in unexpected output. For example, objects or functions created using Object.create() method, which are already explained in the thread by most of the clever folks

1

Use instanceof because if you change the name of the class you will get a compiler error.

Robert Deml
  • 12,390
  • 20
  • 65
  • 92
0

To be very precise instanceof should be used where value is created via the constructor (generally custom types) for e.g.

var d = new String("abc")

whereas typeof to check values created just by assignments for e.g

var d = "abc"
Sambhav
  • 21
  • 1
  • 4
0

According to MDN documentation about typeof, objects instantiated with the "new" keyword are of type 'object':

typeof 'bla' === 'string';

// The following are confusing, dangerous, and wasteful. Avoid them.
typeof new Boolean(true) === 'object'; 
typeof new Number(1) === 'object'; 
typeof new String('abc') === 'object';

While documentation about instanceof points that:

const objectString = new String('String created with constructor');
objectString instanceOf String; // returns true
objectString instanceOf Object; // returns true

So if one wants to check e.g. that something is a string no matter how it was created, safest approach would be to use instanceof.

Laszlo Sarvold
  • 733
  • 7
  • 15
-1

Despite instanceof may be a little bit faster then typeof, I prefer second one because of such a possible magic:

function Class() {};
Class.prototype = Function;

var funcWannaBe = new Class;

console.log(funcWannaBe instanceof Function); //true
console.log(typeof funcWannaBe === "function"); //false
funcWannaBe(); //Uncaught TypeError: funcWannaBe is not a function
Suprido
  • 525
  • 7
  • 17
-1

One more case is that You only can collate with instanceof - it returns true or false. With typeof you can get type of provided something

-1

with performance in mind, you'd better use typeof with a typical hardware, if you create a script with a loop of 10 million iterations the instruction: typeof str == 'string' will take 9ms while 'string' instanceof String will take 19ms

-1

Of course it matters........ !

Let's walk this through with examples.In our example we will declare function in two different ways.

We will be using both function declaration and Function Constructor. We will se how typeof and instanceof behaves in those two different scenarios.

Create function using function declaration :

function MyFunc(){  }

typeof Myfunc == 'function' // true

MyFunc instanceof Function // false

Possible explanation for such different result is, as we made a function declaration , typeof can understand that it is a function.Because typeof checks whether or not the expression on which typeof is operation on, in our case MyFunc implemented Call Method or not. If it implements Call method it is a function.Otherwise not .For clarification check ecmascript specification for typeof.

Create function using function constructor :

var MyFunc2 = new Function('a','b','return a+b') // A function constructor is used 

typeof MyFunc2 == 'function' // true

MyFunc2 instanceof Function // true

Here typeof asserts that MyFunc2 is a function as well as the instanceof operator.We already know typeof check if MyFunc2 implemented Call method or not.As MyFunc2 is a function and it implements call method,that's how typeof knows that it's a function.On the other hand, we used function constructor to create MyFunc2, it becomes an instance of Function constructor.That's why instanceof also resolves to true.

What's safer to use ?

As we can see in both cases typeof operator can successfully asserted that we are dealing with a function here,it is safer than instanceof. instanceof will fail in case of function declaration because function declarations are not an instance of Function constructor.

Best practice :

As Gary Rafferty suggested, the best way should be using both typeof and instanceof together.

  function isFunction(functionItem) {

        return typeof(functionItem) == 'function' || functionItem instanceof Function;

  }

  isFunction(MyFunc) // invoke it by passing our test function as parameter
AL-zami
  • 8,902
  • 15
  • 71
  • 130
-1

Coming from a strict OO upbringing I'd go for

callback instanceof Function

Strings are prone to either my awful spelling or other typos. Plus I feel it reads better.

Keplerf1
  • 84
  • 5