JavaScript: Objects
Tags: javascript, beginners
Published: 2022-08-10 03:22:00

* Variables are containers to store data. **Objects are variables**.
* To create an object, use curly braces`{}`; 
`[]` is used to create an array ;
a variable has one value, doesn't have braces.
* objects store unordered data in a `key: value` pair. Each key:value pair is separated with `,`(Unlike in CSS the properties are separated with `;`).
* There are two ways to access a key's value:

1. `object.propertyname`;

2. `object['propertyname']` This can be used in functions.

```
let doggy = {
color: 'dark orange',
breed: 'golden retriever'
};
function getProp(objectName, propertyName){
  return objectName[propertyName];
}
getProp(doggy, 'breed');   //output: "golden retriever"
```
* If an object is declared by `const`, it can't be reassigned but is still mutable. 
* `method`: when the data stored in an object is a function. An object can have more than one method. 

* A `for...in` loop can iterate through the object.

```
let lifeInHouse = {
  lives: {
   doggy: {
    color: 'dark orange',
    breed: 'golden retriever'
   },
   plant: {
    color: 'green',
    breed: 'N/A'
  }
 }
}
for(let life in lifeInHouse.lives){
  console.log(`${life}'s color is: ${lifeInHouse.lives[life].color}`);  
}   //output: doggy's color is: dark orange
              plant's color is: green
```
* `for ... of` iterates an array.
* **Objects pass by reference. If the object is changed inside a function, the change is permanent. But reassignment doesn't work the same.**

For example:

```
let classmate ={
  name: 'Adam',
  gender: 'F'
}
let changeGender = obj =>{
  obj.gender = 'M'  
}
changeGender(classmate);
console.log(classmate);   //output: { name: 'Adam', gender: 'M' }
```

```
let classmate ={
  name: 'Adam',
  gender: 'F'
}
let reassign = obj =>{
  obj = {
    name: 'Adam',
    gender: 'M'};
  console.log(obj);  //output: { name: 'Adam', gender: 'M' }
}
reassign(classmate);
console.log(classmate);  //output: { name: 'Adam', gender: 'F' }. The reassignment didn't work.
```
When the reassign function is called, the variable obj changes to become a reference of the location of classmate object. So obj has the value of classmate object. However, the classmate variable is remain unchanged. **In short, don't try to use reassign in a function.**

<hr>

* `this` keyword references the calling object. It can provide the properties accesses to other calling object's properties. **Avoid**: don't use arrow function when using this keyword. [Additional resources: Differences between arrow functions and traditional functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions)
* Getters `get functionName(){}` can return different values using conditions. To log the getter result to the screen, use `console.log(objectName.functionName)`. (no parenthesis needed)

```
const robot = {
  _model: '1E78V2',
  _energyLevel: 100,
  get energyLevel() {
    if (typeof this._energyLevel === 'number'){
      return `My current energy level is ${this._energyLevel}`;
    } else {
      return 'System malfunction: cannot retrieve energy level';
    }
  } 
};

console.log(robot.energyLevel);

```
* Setters `set functionName(parameter){}`can reassign values.

```
set newAge(num){
  if(typeof num === 'number' && num >=0){
    this.age = num;
  } else {
    console.log('Please type in a number greater or equal to zero');
  }
};
objectName.newAge = 100;
console.log(object.age);  //output: 100
```
* In factory functions, if the key name is the same as the parameter name, one can be omitted.

```
const foodFactory = (date, type)=>{
  return{
   date,
   type
  }
};
const brioche = foodFactory('July28','bread');
console.log(brioche);  //output: { date: 'July28', type: 'bread' }

```
* When extract values from objects, we can wrap the key name in `{}` then assign it to the object.
* `Object.keys(objectName)` can return the key names of the object.
* `Object.entries(objectName)` can return arrays containing key names and values.

```
for (const [key, value] of Object.entries(object1)) {
  console.log(`${key}: ${value}`);
}
```
* `const newObject = Object.assign(targetObject, source)` will create a new variable with changes and the target object is changed too.

* `const newObject = Object.assign(source, targetObject)` will create a new variable with the change while the target object remains unchanged.