Introduction
Note that this information comes from You don't know JS! Also, I might move this introduction section to a blog article in future.
Contrary to a popular myth saying that everything in Javascript is made of object, not all value types are actually an object. We have primitive value types:
string
boolean
number
bigint
undefined
null
symbol
And we have objects and its sub-types:
Plain object
Boxed Primitives
Built in objects
Arrays
Regular expression
Functions
Primitive values are not object. We cannot assign a property on them.
javascript
myName = "Hui Beom";
myName.nickname = "Zerro";
// TypeError: Cannot create property 'nickname' on string 'Hui Beom'
In contrary, all objects have property. Property is made up of key/value, also known as property name and property value.
javascript
person = {
firstName: "Hui Beom"
lastName: "Kim"
};
In most case, property name is coerced to string value type. Number value type (or integer looking string value) is only exception to this:
javascript
obj1 = {
42: "<-- this property name will be treated as an integer",
"41": "<-- ...and so will this one",
true: "<-- this property name will be treated as a string",
[myObj]: "<-- ...and so will this one"
};
If you have noticed in above code, you can compute the property name when defining object literal:
javascript
obj2 = {
["2023-" + (month + 1)]: false
}
Concise Property
When defining a object literal, we can use shorthand known as concise property to omit the property name. So instead of this:
javascript
coolFact = "the first person convicted of speeding was going 8 mph";
obj3 = {
coolFact: coolFact
};
We can use this:
javascript
coolFact = "the first person convicted of speeding was going 8 mph";
obj3 = {
coolFact
};
Object Spread
We use object spread to retrieve the properties of object and use them in another object as they are defined:
javascript
obj4 = {
favoriteNumber: 12,
...obj5,
greeting: "Hello!"
}
Note that object spread is shallow. It simply assign the properties from the source object to target object. So if the property value of source object was a reference to another object, the reference is copied over to target object. Both source and target object will have reference to the same object in memory, instead of creating a new object.
Defining properties of an object happens in order. So in above example, if obj5 contains property name called favoriteNumber
and greeting
, obj5.favoriteNumber
will override the obj4.favoriteNumber
while obj4.greeting
will override obj5.greeting
. In other words, later defined properties will override the earlier properties with same property name.
Deep Copy
Deep copying an object is complicated because of many edge cases such as copying DOM element, function or cases of circular reference. There is no single standard for dealing with these corner cases and opinions differ from person to person.
There are 3 ways of handling a deep copy:
- Using library
- Using
JSON.parse(JSON.stringify(..))
- Using
structuredClone()
JSON.parse(JSON.stringify(..))
does not work with circular reference and values that can't be serialized to JSON (ex. function). structuredClone
is more recent addition to Javascript environments (it is not part of Javascript specification). It can handle circular reference and more types of value than JSON
round trip, but it still has limitation for supporting functions and DOM elements.