(Not) Everything in JavaScript is an Object

For those who just wants the answers, feel free to jump to the 'Summary' at the end.

This post has also been translated to Russian.

There are a lot of confusion out there as to whether JavaScript is an Object-Orientated programming (OOP) language, or a functional language. Indeed, JavaScript can work as either.

But this lead people to ask "Are everything in JavaScript objects?", "What about functions?"

This post will clear all this up.

Let's start at the start

In JavaScript, there are six primitive data types:

  • Booleans - true or false
  • null
  • undefined
  • number - double-precision 64-bit float. There are no integers in JavaScript.
  • string
  • symbol (new in ES6)

In addition to these six primitive types, the ECMAScript standard also defines an Object type, which is simply a key-value store.

const object = {
  key: "value"

So, in short, anything that is not a primitive type, is an Object, and this includes functions and arrays.

All functions are objects.

// Primitive types
true instanceof Object; // false
null instanceof Object; // false
undefined instanceof Object; // false
0 instanceof Object; // false
'bar' instanceof Object; // false

// Non-primitive types
const foo = function () {}
foo instanceof Object; // true

Primitive types

Primitive types have no methods attached to them; so you'll never see undefined.toString(). Also because of this, primitive types are immutable, because they have no methods attached that can mutate it.

You can reassign a primitive type to a variable, but it will be a new value, the old one is not, and cannot, be mutated.

const answer = 42
answer.foo = "bar";
answer.foo; // undefined

Primitive types are immutable

Furthermore, the primitive types are stored as the value themselves, unlike objects, which are stored as a reference. This has implications when performing equality checks.

"dog" === "dog"; // true
14 === 14; // true

{} === {}; // false
[] === []; // false
(function () {}) === (function () {}); // false

Primitive types are stored by value, objects are stored by reference


A function is a special type of object, with some special properties, such as constructor and call.

const foo = function (baz) {};
foo.name; // "foo"
foo.length; // 1

And just like a normal objects, you can add new properties to the object:

foo.bar = "baz";
foo.bar; // "baz"

This makes functions a first-class citizen, because it can be passed around, as arguments into other functions, just like any other objects could.


A method is a object property that also happens to be a function.

const foo = {};
foo.bar = function () { console.log("baz"); };
foo.bar(); // "baz"

Constructor Functions

If you have several objects which share the same implementation, you can place that logic inside a constructor function, and then user the constructor function to create those objects.

A constructor function is no different from any other function. A function is used as a constructor function when it is used after the new keyword.

Any function can be a constructor function.

const Foo = function () {};
const bar = new Foo();
bar; // {}
bar instanceof Foo; // true
bar instanceof Object; // true

A constructor function will return an object. You can use this inside the function body to assign new properties to the object. So if we want to make many objects with the property bar initialized to the value "baz", then we can create a new constructor function Foo that encapsulates that logic.

const Foo = function () {
  this.bar = "baz";
const qux = new Foo();
qux; // { bar: "baz" }
qux instanceof Foo; // true
qux instanceof Object; // true

You can use constructor functions to create a new object.

Running a constructor function, like Foo(), without new will run Foo like a normal function. this inside the function would correspond to the execution context. So if we call Foo() outside of all functions, it will actually modify the window object.

Foo(); // undefined
window.bar; // "baz"

Conversely, running a normal function as a constructor function would normally return a new empty object, as you have already seen.

const pet = new String("dog");

Wrapper Objects

The confusion arises because of functions like String, Number, Boolean, Function etc. which, when called with new, creates wrapper objects for these primitive types.

String is a global function that creates a primitive string when passed in an argument; it will try to convert that argument into a string.

String(1337); // "1337"
String(true); // "true"
String(null); // "null"
String(undefined); // "undefined"
String(); // ""
String("dog") === "dog" // true
typeof String("dog"); // "string"

But you can also use the String function as a constructor function.

const pet = new String("dog")
typeof pet; // "object"
pet === "dog"; // false

And this will create a new object (often referred to as wrapper object) representing the string "dog", with the following properties:

  0: "d",
  1: "o",
  2: "g",
  length: 3

Object wrappers are often referred to as wrapper objects, too. Go figure.


What's interesting is that the constructor of both the primitive strings and the object are both the String function. What's even more interesting is the fact that you can call .constructor on the primitive string, when we've already covered that primitive types cannot have methods!

const pet = new String("dog")
pet.constructor === String; // true
String("dog").constructor === String; // true

What's happening is a process called autoboxing. When you try to call a property or method on certain primitive types, JavaScript will first convert it into a temporary wrapper object, and access the property / method on it, without affecting the original.

const foo = "bar";
foo.length; // 3
foo === "bar"; // true

In the above example, to access the property length, JavaScript autoboxed foo into a wrapper object, access the wrapper object's length property, and discards it afterwards. This is done without affecting foo (foo is still a primitive string).

This also explains why JavaScript doesn't complain when you try to assign a property to a primitive type, because the assignment is done on that temporary wrapper object, not the primitive type itself.

const foo = 42;
foo.bar = "baz"; // Assignment done on temporary wrapper object
foo.bar; // undefined

It will complain if you try this with a primitive type which does not have a wrapper object, such as undefined or null.

const foo = null;
foo.bar = "baz"; // Uncaught TypeError: Cannot set property 'bar' of null


  1. Not everything in JavaScript is an object
  2. There are 6 primitive types in JavaScript
  3. Everything that's not a primitive type is an object
  4. Functions are just a special type of object
  5. Functions can be used to create new objects
  6. Strings, booleans and numbers can be represented as a primitive type but also as an object
  7. Certain primitive types (strings, numbers, booleans) appear to behave like objects because of a JavaScript featured called autoboxing.

Daniel Li

Full-stack Web Developer in Hong Kong. Founder of Brew.

Hong Kong http://danyll.com