# Objects

# Introduction to Objects in Javascript

# What is an object?

Objects are a type of variables in javascript that act as containers for other types of variables. For example: To connect with real life objects, think about a bicycle, a car or a class-room.

Example In real life, a bicycle is an object, where the bicycle has certain properties, like color, weight, material is made of, type of handle. It also has "functions" or methods like start, stop, change gear, etc.

Based on this the object would be Bicycle it would have properties such as:

  • Weight
  • Color
  • Brand

It would also have methods like:

  • Pedalling
  • Stop
  • Change gear

Hence, all bicycles would have the same Properties but their value will vary between different bicycles. Additionally all bicycles would have the same Methods that can be invoked at different times

# Why are objects so important?

The importance of objects resides in their capacity to encapsulate information. They are the building blocks in javascript, where everything is an object with properties so understanding their behavior is key to using javascript.

# Task

Open the console and create an object

const bicycle = 'bianchi'

After creating the object call its proto

$ bicycle.__proto__
>> String {"", constructor: ƒ, anchor: ƒ, big: ƒ, blink: ƒ,}

$ const bicycleWeigth = 10
$ bicycleWeigth.__proto__
>> Number {0, constructor: ƒ, toExponential: ƒ, toFixed: ƒ, toPrecision: ƒ,}

This shows that any assignment is on its own an assign of an object, moreover that an object is nothing more than another variable.

Assigning values to more than one property to the same object.

var bicycle = { brand: 'oxford', type: 'urban', size: 'm', weight: 10 }

Accessing the object properties using both mechanisms:

bicycle['brand']
bicycle.brand

# Benefits of objects

# When and how to use objects

An object can be used when needing to store and access information without a specific order, and without either predefined properties or methods.

Objects are used to transport information between different parts of the code in an efficient way to encapsulate properties and methods.

It is important to reinforce the part of the definition that says "without a specific order", because objects work as a sort of data dictionary, since that at the time they are passed from one function into another, it's not assured that they order will remain the same within the object.

# Accessing an object properties

As stated before objects can contain any kind of information inside them as a property, even functions.

var bicycle = {
  brand: 'oxford',
  type: 'urban',
  size: 'm',
  weight: 10,
  getTitleName: function() {
    return `Bicicleta ${this.brand} talla ${this.size}`
  }
}

$ bicycle.getTitleName()
>> "Bicicleta oxford talla m"

In the example before, a bicycle object was created, with the properties defined before but now we have added a function that returns a title for the bicycle that is constructed as of certain properties that were accessed using the keyword this that refers to the values of the owner of the function. Another way would be

var bicycle = {
    ...
    getTitleName: () => {
      return `Bicicleta ${brand} talla ${size}`
    }
}

$ bicycle.getTitleName()
>> "Bicicleta oxford talla m"

In this case we have avoided the word this and function() using the arrow operator =>

After we just have accessed the property getTitleName, in the exact same way as we accessed any other property, with the exception that since it's a function it needs to be executed with ()

# Methods of an object

In javascript not everything needs to be created by hand, objects have properties that allow us access to the internal values.

We will review some of the methods more commonly used and explain its function

# Copy of an object

There are two methods for copying an object

# Object.assign()

This methods copies all the properties from one or more source to a specific object, and returns the object

const source = { x: 4, y: 'just y' };

const returnedTarget = Object.assign({}, source);

console.log(returnedTarget);
// expected output: Object { x: 4, y: 'just y' }

There is another methods to copy an entire object into another one with the Spread operator will review in deep later, but to copy an object we could use it this way.

const source = { x: 4, y: 'just y' };
const newTarget = {...source};

# Spread operator over objetos

The spread syntax can be used on different kind of variables, in this case we will focus mainly on object

Let's suppose that we have a function that when executed it returns a part of an object and then we have another function that returns another part of the object and we want to merge them together.

const firstPart = { firstName: 'Juanin', lastName: 'Harry' }
const secondPart = { tvShow: '31 minutos', position: 'productor' }

const finalCharacter = {...firstPart, ...secondPart} 

console.log(finalCharacter)
// expected output: Object { firstName: 'Juanin', lastName: 'Harry', tvShow: '31 minutos', position: 'productor'  }

This allows us to merge all the properties and values inside of each object and assign them to another object that contains all these properties

This functionality is also used to add values to an object without modifying the original object. Let's say we would like to add middleName to our character without modifying the original object

const withMiddleName = {...finalCharacter, middleName: 'Juan'} 
console.log(withMiddleName)
// expected output: Object { firstName: 'Juanin', lastName: 'Harry', tvShow: '31 minutos', position: 'productor', middleName: 'Juan'  }

We had already merged our object, now we are adding the new property along with the original object's inner state to a new object.

# hasOwnProperty()

Considered we have an object described as below:

const user = {
	id: 1,
	names: {
		firstName: 'Juanin',
		lastName: 'Harry' 
	}
}

Where a user has an name object inside and you would like to access firstName, then you can use the syntax to access an object properties like below

console.log(user.name.firstName)
// Expected Output -> 'Juanin'

there is no issue with this but what would happen if you try accessing a property and you are not sure the object has it, e.g. middleName

console.log(user.name.middleName)
// Expected output -> (?)

This will return undefined since the propues has not been defined yet/ So before trying to show something as undefined, you could use the method hasOwnProperty to check whether the object has the property or not.

user.name.hasOwnProperty('middleName')
// Expected output -> false
user.name.hasOwnProperty('firstName')
// Expected output -> true

# Object.keys()

This is a method of objects in javascript that returns all the keys/properties of the object it is called upon. It's specially useful when trying access all they keys in an orderly fashion

const user = { firstName: 'Juanin', lastName: 'Harry', tvShow: '31 minutos', position: 'productor' }

console.log(Object.keys(user))

// Expected output -> Array ["firstName", "lastName", "tvShow", "position"]

It can also be combined with a for to loop through all these keys and access their values.

const user = { firstName: 'Juanin', lastName: 'Harry', tvShow: '31 minutos', position: 'productor' }

const userKeys = Object.keys(user);

for (let  index = 0; index < userKeys.length; index++) {
	console.log(user[userKeys[index]])
}

// Expected output ->
//> "Juanin" 
//> "Harry" 
//> "31 minutos"
//> "productor"

# Object.values()

There is also a functionality to ease the above which makes the example easier

const user = { firstName: 'Juanin', lastName: 'Harry', tvShow: '31 minutos', position: 'productor' }

const userValues = Object.values(user);

console.log(userValues)
// Expected output -> Array ["Juanin", "Harry", "31 minutos", "productor"]

userValues.forEach(element  => {
	console.log(element);
});

/* Expected output -> 
> "Juanin"
> "Harry"
> "31 minutos" 
> "productor"
*/

# Why it's better copying over assigning

We have reviewed some useful methods, most of them tend to return a new object. The reason is because of the way javascript works and because it's a functional language, where each function is executed, dumped into memory and then the memory that was allocated is freed up, this makes reassigning a very cheap process for the application. Hence in javascript we always try to work with immutable objects, this means that we rather avoid modifying an object over creating a new one with the same values, make the necessary changes and return the updated one.

Why do we say it's functional? is a programming paradigm that avoids changing states, in which functions only depend on their own incoming arguments, and everything that occurs inside the function is visible. Making it really predictable at every moment.

There are other programming paradigms, like object-oriented programming, in which objects are used to represent values, these objects are data structures that can hold information and that information is only accessible via the methods of the class.

At a high level in the object-oriented programming paradigm everything is stored in structures that need methods to access them, whereas in functional programming, everything is about transforming data, getting parameters and transforming them into new values and new versions of them.

# Destructuring

Until now, we knew of ways to access properties inside an object, how to access functions inside an object, how to recognize it, and how to determine if there is a certain value in it, many times we would like to get specific values of an object. For example, if we have the following user object

const user = { firstName: 'Juanin', lastName: 'Harry', tvShow: '31 minutos', position: 'productor' }

and we want to only get it's position, we could use the destructuring assignment the following way

const { position } = user
console.log(position)
// Expected output -> "productor"

The method above does is to search inside the user object the property position and copy its value into a new variable called position, it assigned the key of the object to the value of the object. Now if we want to obtain more values of the same object it's also possible to do

const { firstName, tvShow } = user
console.log(firstName)
// Expected output -> "Juanin"
console.log(tvShow)
// Expected output -> "31 minutos"

Let's imagine now that we need to create a function that given an object needs to show the user name and the program it belongs to. There are two ways of achieving this, one with deconstruction and another without it.

const nameAndShow = (user) => {
	const {firstName, tvShow} = user;
	return `${firstName} pertenece al programa ${tvShow}` 
}

whereas if we use the destructuring assignment while calling the function

const nameAndShow = ({firstName, tvShow}) => {
	return `${firstName} pertenece al programa ${tvShow}` 
}

the output will be the same and the code cleaner

# Sources

#