In JavaScript we have values. A value is a thing. There are many types of values, including objects, arrays, functions, numbers, strings, and booleans. To differentiate between the nature of values, we have a term called data types
In JavaScript there are two types of data types:
- Primitive values
- Non-primitive values
Okay, let’s talk about the difference between primitive and non-primitive values in JavaScript.
Primitive Values
Primitive values are things like numbers, strings, boolean, and undefined.
Try printing out the following primitive values in your console:
console.log(4)
console.log('Johnny')
As you can see, the output you get from printing out primitive (simple) values is predictable and not hard to reason about. You ask your console to print out 4, and you get 4, you ask it to print out Johnny, and you get Johnny.
Why are they called primitive values? Because they’re simple (simple values would’ve been a better term for them if you ask me). They’re simple (primitive) in the sense that they are the type of data value that don’t contain properties — unlike non-primitive values which are more “complex” data types, and which we’ll discuss in a moment.
Non-Primitive Values
— aka Complex/Special Values
In JavaScript, objects and functions are considered non-primitive values.
You’ll sometimes hear non-primitive values referred to as:
- object references
- complex data types
- special values
These are just alternative ways of referring to values that are not primitive. Yes, it’s annoying with all those synonyms, but you must be aware of them. You can read entire articles on the web that deal with this topic, which only uses one of these terms. A little later you’ll read an article by a different author who uses another term, and then you’ll wonder if you’re even reading about the same language.
Unlike primitive values, non-primitive values do contain properties,
Objects
Try printing out the following in your console:
console.log({})
console.log([])
Do you notice something different about this output compared to the primitive value examples earlier?
We can click and expand on these outputs. Try clicking on the arrow next to each output (just click one time on each) and see what happens.
Aha, now each has a name. The first is called Object, the second is called Array.
Note: if you’re using Firefox, you might not have to click on the arrow to unveil the data type.
The above are both objects. An array is a type of object in JavaScript — an array object — but it can do different things than regular objects.
To prove that arrays are indeed objects in JavaScript, run the typeof
operator on the examples above, like this:
console.log(typeof {}) // object
console.log(typeof []) // object
Yup, they’re both objects.
Okay, now try clicking on the arrows next to your object and array object again, and see what happens.
Holy crap, now things don’t look so simple anymore, do they?
What you’ve uncovered, are all the different property types that regular objects and arrays (a type of object) contain respectively.
Don’t worry about understanding any of this stuff right now, my point is only to show you that objects are not simple value types (they are non-primitive) because they can do a lot of things, unlike primitive values.
Functions
So far you’ve seen objects (regular objects {}
& array objects []
), now let’s take a look at functions. Try printing out the following in your console:
console.log(function doSomething() { })
If you’re using Chrome, you probably won’t get an expandable output — I don’t know why Google/Chrome designed it like this. If however you try printing out the line above in Firefox, you’ll get a detailed output like this:
As you can see functions also have properties but different types than objects.
arguments: null
— we have no arguments/parameters inside the()
.caller: null
— we don’t call the function from anywherelength: 0
we have no arguments (zero).name: "doSomething"
— the name of our function.
You also have access to the prototype: Object
and <prototype>: function ()
which will unveil a lot more info about functions, just like you saw earlier with objects.
Wait, why does it say prototype: Object
? Is a function considered an object?
In JavaScript, every non-primitive value type is to some extent considered an object, including functions (and arrays, as you saw earlier). More specifically, in JavaScript, a function is a function object — a special type of object that can be called with the ()
syntax, as you saw in the doSomething()
example.
Now it probably makes more sense to you why I mentioned earlier that non-primitives are sometimes referred to as object references.
Try running the typeof
operator on your function and see what happens:
console.log(function doSomething() {})
It outputs function
...
Are you surprised by this?
If everything in JavaScript is an object, why does it output function
as the type?
Well, look at the screenshot from earlier again:
It says that the function has both a function prototype and an Object prototype.
What happens, and let me make this clear, as I understand it is that in JavaScript the function prototype inherits from the Object prototype.
So a function is indeed its own special data type value (with its own prototype) and should be treated as such since it can do different things than regular objects. But a function has its roots in the so-called Object prototype, so even though it’s its own thing, it still falls under the object umbrella.
Summary
Because of the wide range of options we have with objects and functions we call them non-primitive data types (“complex”) unlike primitive data types (“simple”) such as number and strings, which have limited options in comparison.