Object oriented JavaScript part 2
Tags: javascript, oop
Published: 2020-11-30 23:38:27

#Introduction
This is part 2 of my notes on The principles of object oriented programming in JavaScript by Nicholas C. Zakas. This post will be on functions and how they relate to object oriented programming in JavaScript. If you have questions or concerns about this post feel free to reach out to me on [twitter](https://twitter.com/Tristanthewebd1).

###Functions
- Functions in JavaScript are just normal objects. However, they are distinguished from other objects by an internal property called [[Call]]. This internal property signals to the JavaScript engine that it can be executed and only functions have this internal property

###Function Declarations
- A function declaration, also know as a function statement simply defines a function with a certain amount of specified parameters. However, a JavaScript function will not get mad at you if you call your function with more parameters than originally specified. JavaScript will simply ignore the extra parameters. By default these kind of functions return undefined and you have to use return at the end of the function in order to get it a proper value. Below is an example of a simple function declaration returning the number 4. This means that any time you call this function it will always return the number 4.
      
              function example(){
                return 4
              }

- It should also be noted that function declarations are "hoisted" to the top of the function or global scope. The consequence of this is that you can use a function before it is defined. Below is an example.

            num(4)
            function num(x){
               return x
            }

- The code block above shows that the function num is called before it is defined. This is possible because the function is "hoisted" to the top of the scope.


###Function Expressions
- Function Expressions are very similar to function declarations and are almost identical. However there are two major differences, one being that function expressions are not hoisted. This means that unlike function declarations we can not use function expressions before they are declared. The other difference is that function expressions do not have names, because of this They are also called anonymous functions. You will see anonymous functions used in [Immediate Invoked Function Expressions(IIFE)](https://developer.mozilla.org/en-US/docs/Glossary/IIFE). IIFEs will be explored in a later post. Below is a simple example of a function expression.
       
           const peanut = function(){
              console.log('it is what it is')
           }

###Arrow Function
- The arrow function is just a simplified and alternate version of the function expression. However, there are some pretty major differences and limitations for arrow functions. The biggest one is that it does not have its own binding to 'this'. If you are unfamiliar with 'this' I would strongly urge you to google it, there are many good articles pertaining to that subject. With that being said, another major limitation is that arrow functions are not suitable for the call, bind or apply methods, we will talk about those methods later in this post. Arrow functions have become the standard and you should get to know them as soon as possible. Below is just a simple demonstration of the arrow function to show off the syntax.

         const purpose= (x)=>console.log('you pass butter')

- As you can see the syntax is much more compact then the normal function expression. With the rise of functional programming it has won over the hearts of the developer community.


###Functions and Objects
- In JavaScript functions are declared "first class" which means that they can be treated just like any other variable. Functions can be added to objects, assigned to variables and returned from other objects, this makes JavaScript very powerful. Below is an example of "first class" JavaScript functions.

         let obj ={
            name:function(){console.log('bob')}
         }

         let funcVariable = function(){
                               console.log('it do go down')
                            }
        function hof (){
           return funcVariable
        }

        function example(functionHere){
           return functionHere
        }

###Overloading
- Most object oriented languages support overloading by having a single function support multiple [signatures](https://stackoverflow.com/questions/2322736/what-is-the-difference-between-function-declaration-and-signature). Since JavaScript functions can accept any number of parameters, creating a signature in JavaScript is not possible. However, we can imitate it by using the arguments object( which holds the number of arguments). Below is an example of how we would do just that.

        function talk(message){
           if(arguments.length === 0){
                console.log("this is the default message")
           }else{
                console.log(message)
           }
        }


- When the talk function is ran it will first check if we have entered any arguments. it does this through aruments.length and if that is equal to 0 then we console.log the default message, else we call the message argument. On a side note, arguments and  parameters are different. A parameter is simply a placeholder for a value and is used when we are initialy writing our function. When we call the function that is when parameters become arguments. 

arguments = data  parameters = placeholders


###The This Object
- Every scope in JavaScript has a 'this' object. In global scope it is the window object and when a function is called attached to an object 'this' is that object by default. This means that instead of referencing the object in a function we can reference  'this'. Below is an example of how the 'this' object can we used inside of a function.

          let person ={
              const name ="Bob",
              speak:function(){
                console.log('my name is' + this.name)
              }
          }   
-If we were to call the method (person.speak()) it would output 'my name is Bob'. The 'this' object is very convenient but it can also be very confusing at times. Since the 'this' object it determined when you call the function, it can lead to many bugs. The functions listed next are ways we can determine the value of the 'this' object.

###Changing The 'this' Object
- When you need to change the value of 'this', one option is to use the call() method. The call() method accepts any number of parameters but the first one must be the object that 'this' is being bound to. All the other parameters will passed to the function that call() is being applied to. Below is an example of how one might use it.

          function speak(message){
             console.log(this.name + " said " + message)
          }

          let person ={
             name:"bob"
          } 
      
        speak.call(person,'it do go down')

- when speak() is called with the call() method, the 'this' value will represent the person object and the argument of 'it do go down' will be passed to speak.

#### The apply method()
- This is another method that is used to change the 'this' object. It works the same as call(), except it's second parameter is an array of parameters that will be passed to the function. Below shows how the apply method works.

        function speak(message){
             console.log(this.name + " said " + message)
          }

          let person ={
             name:"bob"
          } 
      
        speak.apply(person,['it do go down'])

- As you can see it is almost identical to the apply method, the only difference is that the second parameter is an array 


#### The bind method()
- This is the last and final method used to change the 'this' object and it behaves a little different from the other two methods. Like call it accepts any number of parameters, the first being the new 'this' object and the second being parameters to be passed to the function. Where it is different is that it returns a new function that has a bound 'this' value. If this is confusing, just look at the example below and things should become clear.


        function speak(message){
             console.log(this.name + " said " + message)
          }

          let person ={
             name:"bob"
          } 
      
         speak.call(person,'it do go down')

        let person1 = speak.bind(person,'it is what it is.')

        person1()

- As you can see still very similar but now that variable holds a function that is bound to the person object. Very useful  

###Conclusion
- This is the end of part two in my object oriented programming in JavaScript series. Part 3 is going to be on Objects and developing a deeper understanding of them. If you have any thoughts or complains on this post please make sure to contact me via [twitter](https://twitter.com/TristAndroidDev)