More JavaScript Data Types
Data types are fundamental part of JavaScript language. If you want to get good at JavaScript, you have to know how these data types work and how to use them. This article will help you learn what you need to know about BigInt, boolean, null, undefined, symbols and objects.
Data types
In the previous part, you’ve learned about the first two data types that exist JavaScript. These were strings and numbers. Now, let’s take a look at the rest of them.
BigInt
BigInt
is one of the data types added to JavaScript language recently. The BigInt
type allows you to work with numbers bigger than 2^53 – 1. Before BigInt
, there was no way to work with such large numbers in JavaScript. The number
primitive data type can’t handle these numbers. There is a safe integer limit for Number
type.
BigInt
was created to bridge this gap. BigInt
allows you to safely work and store with large integers, even integers exceeding the safe integer limit. Since the purpose of BigInt
is to deal with very large numbers it is unlikely you will use it very often. That said, it is still good to know there is such data type, and how to work with it.
There are two ways to create a BigInt
. The first way is by appending “n” to the end of an integer, such as 6562324949863231n
. The second way is by calling BigInt()
function. In this case, you use the number as an argument-put it inside the parentheses-such as BigInt(6562324949863231)
. This will create the same result as using the first way.
BigInt and arithmetic operations
Similarly to the Number
type, you can do arithmetic operations with BigInt
as well. You can add, subtract, multiply or divide them. When you want to do so, remember that you can do these operations only when all numbers are data type of BigInt
. If you try to, for example, multiple a Number
by BigInt
, it will lead to an error.
Another thing to remember is that arithmetic operations with BigInt
numbers will always return BigInt
numbers. Arithmetic operations with BigInt
will never return the decimal part. There will be no floats at the end because the results will always be rounded towards zero.
BigInt type is not a Number type
BigInt
type is not a Number
type. This is important to remember, especially for comparison. When you try to compare BigInt
of zero with zero, it will work only if you use loose equal. Loose equal will result in true
. On the other hand, if you use strict equal, it will result in false
.
The reason is that strict equal compares both, the value as well as its data type. So, yes, the values are the same. Both are zero. However, the data types are different. One is BigInt
and the other is Number
. In order for things to be equal, both conditions must be “truthy”. They are not. So, the result is false
. Other than that, you can compare BigInt
with Number
as you want.
From Number to BigInt and back
When you want to covert between these two data types you can use BigInt()
, to convert number to BigInt
, and Number()
, to convert BigInt
to number. Since BigInt
allows to work with numbers larger than Number
can handle, remember that if the BigInt
is too big for the Number
type, any extra bits will be cut off. So the precision will be lost.
When you want to convert some number to BigInt
make sure the number is an integer. Otherwise, it will not work. When you try to convert float to BigInt
JavaScript will throw an error. One more thing. As you know, it is possible to convert string
to a Number
. The same is also possible with BigInt
. You can convert string
to BigInt
.
BigInt and booleans
One more thing about BigInt
data type. When you use this data type in conditional statements, such as if
, or other boolean operations, BigInt
will behave like Number
. For example, number zero is always “falsy”. Numbers higher, or smaller, than zero are “truthy”.
The same rule applies to BigInt
. BigInt
equal to 0n
is also “falsy”. BigInt
bigger or smaller than 0n
will be “truthy”.
Boolean (logical type)
Boolean
is one of the simplest data types in JavaScript. It is a logical type that can be either true
or false
. You can think about true
as “yes” and false
as “no”.
Truthy and falsy
In JavaScript, when you use value in boolean context, such as if
conditional statement, that value is converted to boolean. It can become either true
or false
. Which boolean
it will is determined by the “type” of the value. Value can be either “truthy” or “false”. Truthy value will become true
and falsy false
.
Fortunately, there is an easy way to remember which values are truthy and which are falsy. Values that are falsy are 0
, 0n
(0 BigInt
), ""
or ''
or ``
(empty string), null
, undefined
, NaN
and of course false
). Any other value is truthy.
Null
Next is null
. This one is special. Null
is a subtype of other default types that contains only the null
value. In other programming languages, null
is used as a reference to a non-existing object or null pointer. This is not the case in JavaScript.
In JavaScript, null
represents “unknown value”, “nothing” or “empty”. In boolean context, null
value is falsy. One more thing. Programmers sometimes use null
as a value for variables whose values are “empty” or unknown.
Undefined
undefined
is very similar to null
. It is also special value, a subtype of other default types that contains only the undefined
value. The meaning of undefined
can be translated as “value is not assigned”. The best example to illustrate this is declaring a variable without assigning it.
When you declare a variable, but you will not assign it any value, its value will automatically be undefined
. Similarly to null
, undefined
is also falsy in boolean context. One more thing. You can assign undefined
to a variable. However, this is not a recommended practice. It is better to assign it null
.
Symbols
Similarly to BigInt
, Symbol
is also one of the data types that were recently added to JavaScript. The Symbol
type represents a unique identifier. The main use of Symbol
is creating unique identifiers for objects. For example, you can create hidden properties on objects.
When you want to create new Symbol
it is by using Symbol()
. You can also provide a description of the symbol, or name of the symbol. You can do this passing a string
between the parenthesis. As we already discussed, symbols are always unique. This applies even if you specify a symbol name.
Even if you decide to create a couple of symbols, with the same name, they will still be different. The values will be different. That symbol name has no real effect for JavaScript itself, only for you. For example, for debugging.
Symbols as hidden object properties
As we discussed, one common use case for using Symbols
is to create hidden properties on objects. Hmm, hidden? When you create a property on object some 3rd party code can access it accidentally and re-write it. In case of a Symbol
, this will not happen. They can’t be accidentally accessed and re-written.
When you use for…in loop, it will not reveal any Symbol
. Not even Object.keys()
, or Object.values()
, will be able to reveal anything. If you can’t find it, you can’t access it and/or change it, even if you want. One thing, although Symbols
will not be detected by Object.keys()
, they will work with Object.assign()
.
One thing to remember. When you want to use a Symbol
in an object literal, to create a symbol property, you need to wrap that Symbol
inside square brackets ({ [someSymbol]: value }
).
Symbols and cloning objects
When you create a clone of an object, using Object.assign()
, it will copy its whole content. This also includes any Symbols
(symbol properties) inside it. This makes sense. When you want to create a clone of an object you want that clone to be a 1:1 copy.
It would not be a 1:1 copy if some properties were missing, those properties created with Symbols
. It is 1:1 copy only when the content is 100% identical. This includes properties created with Symbols
, or symbol properties.
Objects
All the data types we discussed so far were “primitive”. “Primitive” means that they can contain only one thing. For example, a Number
can only contain one number while String
can only contain one string. Objects are different. Objects can store more than just one “thing”. What’s more, they can store multiple “things” of multiple types.
Creating objects
There are two ways to create an object
. The first one by using object literal syntax. In this case, you use curly brackets ({}
) containing a list of properties, key/value pairs. This list of properties is optional. The second way is by using object constructor, or new Object()
.
Which one you choose depends on your preference. That said, it is often easier, faster and more effective to use the object literal syntax. When you decide to go with object constructor you can then have to add properties (key/value pairs) using the dot notation (obj.property = ...
). This works for object literal syntax as well.
However, when you use object literal syntax, adding properties (key/value pairs) is much faster. You don’t have to create the object and then use dot notation. Instead, you can add properties (key/value pairs) right away, when you create the object.
In case of object literal, when you want to add property that contains multiple words, you must wrap that property, those words, with quotes ({'some property': someValue }
). In case of object constructor, you have to wrap the property with quotes and square brackets (obj['some property'] = someValue
).
When you want to access that multi-word property, you use quotes and square brackets again (obj['some property']
). This also works for accessing one-word properties (obj['property']
). Or, you can access the property using without brackets and quotes, using dot notation (obj.property
).
Lastly, you can also delete existing properties. You can do this by using delete
keyword followed by the object name and property (using dot notation).
Square brackets and computed properties
As you know, adding multi-word properties works only when you use square brackets and quotes. This is due to a limitation in variable naming, i.e. it can’t contain any spaces. So, remember to always use square brackets and quotes when you want to add multi-word property. Otherwise, you use camelCase, or something similar and remove spaces.
When you use object literal, you can also use square brackets to reference a variable. When you do this, the value of that variable will be used as the name of the property. This, new, property is called computed property. Remember, when you use this approach, you have to use the value of that variable when you want to access the property, not the name of the variable.
When you use square brackets you can also use more complex property names. For example, you can combine, or concatenate, computed property with strings.
For…in loop, keys and values
When you want to get all keys, or values, inside an object
one thing you can use is for...in
loop. Or, you can also use Object.keys()
for getting all keys and Object.values()
for getting all values. In case of for...in
loop the syntax is simple. You specify variable for keys and what object you want to loop over.
When you use the key variable, inside the loop, you will get object key. You can also combine the key and object name to get the value.
Using “in” operator
When you want to check if specific property exists in an object
there is a faster way. You can use in
operator. The syntax is very simple. You use the property name in the form of a string
, followed by the in
operator, followed by the object
you want to check. If the property exists, it will return true
. Otherwise, it will return false
.
Copying objects
When you work with objects, there is one thing you have to remember. In JavaScript, objects themselves are not copied. What is being copied instead is the reference to the original object. This is called copying by reference. Or, creating a [shallow copy]. Put simply, no new object is created. There is still one object, but there are two variables referencing that object, the same object.
Why is this important? There is still only one object. So, when you change that object all its copies, all variables referencing that object, will be changed as well!
This is not true for primitive data types we discussed, such as strings, numbers, etc. When you copy a string, new string is created. So, when you change the original string, it will not change the copy. The copy will remain untouched.
Cloning objects
So, if, in the future, you change the original object, the clone will not be affected. It will remain untouched. This assign()
method accepts two parameters. First is target
and second is source
. When you want to create new object by copying another you use empty object as the target
({}
) and the original object as the source
, i.e. Object.assign({}, originalObject)
. If you use some object as target
it will be changed as well.
Merging objects
One more thing. The Object.assign()
can also be used for merging objects into a new one. The process is the same as when you create a copy. You use empty object
as the target
({}
). However, for the source
, you now use all objects you want to merge into the new object
, i.e. Object.assign({}, objOne, objTwo, objThree)
.
Conclusion: Understanding Basic JavaScript Data Types
Now, you know about all seven data types that exist in JavaScript. You know how these data types work, how to use them, and what gotchas to pay attention to. Now, take time to review and practice what you’ve learned so far.
Last updated
Was this helpful?