Sarah Ransohoff /engineering

Typeof, Instanceof, and Constructor

While working on a project, I came across a confusing failing test:

// this test
it('should return an html string', () => {
  expect(createElement(node)).to.be.instanceof(String);
});
// was failing
1) createElement module createElement should return an html string:
AssertionError: expected '<div style="text-align: center; color: blue; margin: 20px" id="vdom"><p style="font-size: 20px;">12345</p></div>' to be an instance of String

Why, though? createElement(node) does, in fact, return a string. I went to the console to experiment.

These things seemed to be in contradiction. How could n be a type of string, where the constructor is the String function, but is not in fact an instance of String?

With the help of James Porter, I found this helpful StackOverflow post which explains how string literals "are a different kind of object than objects created from within Javascript." So, for example, creating a string literal

var string = 'boop';
typeof string; // 'string'
is different from creating a string object using the String function.
var string = new String('boop');
typeof string; // 'object'
These two vars, while they both behave as strings as far as we are concerned, are not the same: one is a literal and the other is an instance.

JavaScript is a prototype-based language (versus class-based). So, objects aren't instances of a class. Rather, you can only check if an object has another object in its prototype chain somewhere.

The syntax for instanceof is

object instanceof constructor

where it "tests whether an object has in its prototype chain the prototype property of a constructor" (from the MDN docs). And since literals are not an object, while a string created by the String constructor is, the string literal is not an instance of String.

JavaScript wat.

05 Oct 2016