
Introduction image
Object is created with curly braces — {…} with optional list of properties. A property is a key value pair.
key is always a string type but value can be anything.
Behind the scene object work as a cabinet and each property as a file.

There are two ways to create an object:
Object literals
let user = new Object()
2. using curly braces
let user ={}
There are two ways you can add properties to your object
For simple property addition you can use ‘.’ operator.
If you have a valid variable identifiers like no space, dose not start with a digit, does not include a special character
user.name ="John"
Square brackets are used to add more dynamic properties and special properties.
They are more powerful but more cumbersome to write.
let key = 'surname';
user[key] = 'Smith';
// user ={name:'John', surname:'Smith'}
// second scenario user['address_one']='address'
**Note: **use key in quotes only when there is a space in the key name “surname full”
user={ name:'John' "surname new":"Smith" }
There is no limitation to the property name you can name your key even — **for, let , return. **If your key name is a number then it will be converted to string 0 → ‘0’.Only you can not name your key — ‘proto’
console.log("name" in user) // true
console.log(user.age) // undefined
if property is undefined then it can assume that the property does not exist The problem can be raised when some great person does this
user.age = undefined;
P.S = Don’t be that person
let user ={ name :"john", surname :"smith" }
for(let key in user){
console.log(user[key])
}
Integer properties will ordered in ascending format where as others are ordered in their way they are created.
So whenever you assign any variable value to the object they will denote the same object so basically the reference is assigned.
It’s like two keys to same cupboard.

Shallow copy of an object
Objects can be copied by following ways:
let user. ={name : "John", surname :"Smith"};
let clone ={};
for (let key in user){
clone[key] = user[key]
}
let user. ={name : "John", surname :"Smith"};
let clone ={... user};
You can use Object.assign(objectThatHaveToBeCopied, objectThatWillCopyYourContent)
let user. ={name : "John", surname :"Smith"}
let clone ={};
Object.assign(user,clone)
Note: The problem with object.assign is that it won’t be able to copy the nested object.
Nested Object
let obj ={
name:"John",
surname:"Smith",
address: {
street:"Baker Street",
city:"London",
country :"UK"
}
}
So Object.assign clone will refer to address object instead of creating the copy.
To avoid the previous problem we use structuredClone
let obj ={
name:"John",
surname:"Smith",
address: {
street:"Baker Street",
city:"London",
country :"UK"
}
}
let clone = StructedClone(obj)
This will also fail if object has function property. In that case put your JS hat and write a function to create a deep copy of the object.
delete user.name
Note: It will not delete the whole object.
So if any object, function is reachable means is being accessed either in running a function or declared globally or even is being refer to by some other object then it is reachable and called roots.If the object is reachable then it is it will stored in the memory if the reference is lost or is not being used ever it will be removed . This process of removing the unused objects is called Garbage Collection.
Various methods for optimisation of garbage collection
Generational collection: So new object are checked as they are added as object has a very short life span and they do their work and die.
Incremental Collection : So big objects are broken up to small and then process
Idle-time Collection: Run only when your CPU is idle.
Object can have functions called methods as their properties and these methods want to access the properties like string and number.
let user ={
name:'John',
sayHi(){ console.log(`Hi I am ${this.name}`);
}
}
Like in the above example and you can access it by this.
Note: this is not bound means this will try to access next scope if use strict is not used]
Note : Arrow function does not have this.
You can create similar objects using constructor.
Conventions about constructors are their name starts with capital letter.They are called using new and basically this is assigned to the object and properties are added.
function User(name){
this.name = name;
this.person = true;
}
const firstPerson = new User('jon')
function User(name){
this.name = name;
this.person = true;
}
const firstPerson = User('Draco') // undefined
const secondPerson = new User('Jon')//{name:'Jon', person:true}
If constructor don’t have return statement then you can call it without parenthesis.
function User(){
this.name = 'Jon';
this.person = true;
}
const firstPerson = new User // same as new User()
We can use chaining
obj.props?.value
// if props is present then it will return the value
//if not then undefined
obj.props?.[value]
// Same thing like above obj.method?.()
// if method is present then rin the method or else return undefined
There are three property flags present in any object:
Writable
Enumerable
Confirgurable
These properties are not visible about any key in an object.
To see these property we need to use
let user ={name:'John'}
const descriptor = Object.getOwnPropertyDescriptor(user,'name');
//
{
"value": "John",
"writable": true,
"enumerable": true,
"configurable": true
}
If we want to change these default value then you can create property using defineProperty key word
let user ={}
Object.defineProperty(user,'name',{value:'Jon',writable:true})
const descriptor = Object.getOwnPropertyDescriptor(user,"name")
//{
"value": "John",
"writable": true,
"enumerable": false,
"configurable": false
//}
let user ={}
Object.defineProperty(user,'name',{value:'Jon',writable: false})
const descriptor = Object.getOwnPropertyDescriptor(user,"name")
//{
"value": "John",
"writable": true,
"enumerable": false,
"configurable": false
//}
user.name ='Pete' // give error if strict mode is there otherwise no error
Before that we need to understand what non- enumerable means
let user ={
name:'jon',
sayHi: function(){
console.log(`Hi ${this.name}`);
}
}
if we want to run the loop as in then both name and sayHi will be iterated and to avoid that we can use
Object.defineProperty(user,'sayHi',{enumerable: false})
Object.keys(user) //[name]
There could be a condition where we want to make sure that an object cannot be changed like Math.PI we don’t want someone to do Math.PI = 3.
Once an object is non-configurable i.e {configurable:false} then it cannot be reverted back.
You cannot change its value neither can make their other values like writable and enumerable
only if writable → true will be changed to false
let user ={}
user.defineProperties(user,
{name:{value:'Jon',writable:true},{surname:{value:'Snow' ennumerable: true}}
)
let clone = Object.defineProperties({},Object.getOwnPropertyDescriptors(obj))
This is the better way clone any object as it copy descriptor as well.
Sealing object means you cannot add new properties or delete existing properties.
you cannot add any new property to object.
To check if an object is extension able we can use Object.isExtensible(obj)
Neither can add nor can delete any properties.
To check if the object is sealed Object.isSealed(obj)
Neither can add , change nor delete.
To check if object is frozen use Object.isFrozen(obj)
Setter and getter methods give us the flexibility to add property based on certain condition.
let user ={
name:'Jon',
get sayHi(){
console.log(`Hi ${this.name}`)
},
set sayHi(value){
if(value.trim().length<2){
console.log('name is too short');
return
}
this.name = value;
}
}
user.sayHi // Hi Jon
user.sayHi = 'm' // name is too short
user.sayHi = 'Mary'
user.sayHi // Hi Mary
This is the comprehensive note about object which can help you to understand the basics of it.
Hope you enjoy this article.
