DEFAULT PARAMETERS
Example -
PASSING AS ARGUMENTS (PRIMITIVES VS NON-PRIMITIVE DATA-TYPES)
When we pass a primitive data-type as an argument to a function, the
function makes a COPY of the original value, and works with it.
On the other hand, when we pass a non-primitive data-type as an
argument to a function, the function makes a copy of the REFERENCE
that points to the place in the memory where the object is stored.
This copy points to the value itself. Because of all this, the
original object can be modified from inside of a function.
We should never change the values of non-primitives like objects
inside a function, because that can have unforseeable circumstances.
Also, JavaScript is again different as,
In programming languages, Arguments can be passed by value, or
passed by reference.
JS does not have passing by reference, only passing by value...
If pass by reference was there in JS, then value of NON-PRIMITIVE
data-types could also be changed from inside the function.
FIRST-CLASS FUNCTIONS -
It means that functions are simply values and just another type of
objects. Therefore -
We can store functions in variables or as object methods.
We can pass functions as arguments in other functions.
We can return functions from functions.
We can call methods on functions.
HIGHER-ORDER FUNCTIONS -
It basically is a function that recieves a func as an arguement or
it returns a func or both.
Example -
AN EXAMPLE OF FUNCTION RETURNING FUNCTION -
THE CALL, APPLY AND BIND METHOD
CALL METHOD -
It is a method that is applied to function because functions are
objects. Here the first argument defines that what should "this"
keyword be equal to.
APPLY METHOD -
Same as call method, only diff is that, second argument is an array
of the arguments.
BIND METHOD -
This method does not call the function to which it is attached,
instead it returns a new function where the "this" keyword is
permanently set.
Note - If we try to save the call or apply
method, we will get an error, because call() invokes a function
immediately, whereas bind() creates a copy of the function with a
preset value of 'this'.
If we want to call a function later
with preset arguments, then we use bind() method.
With Event Listeners
Partial application -
This means some
of the arguments of a function are predefined.
IIFE - Immediately Invoked Function Expression
It's just a function expression that is only executed once.
We
have to wrap the function expression around ().
IIFEs were used for data privacy, i.e., to not allow certain
variables to be modified from the global scope. Since variables
declared with var, let or const are function-scoped, that's why we
used IIFEs to define certain variables that cannot be modified from
the global scope.
Example -
Variables declared with let or const are block scoped as well, so we can use that as well for data privacy.
CLOSURES
A CLOSURE makes a function remember all the variables that existed
at the function's birthplace.
The secret of the closure is basically this - Any function always
has access to the variable environment of the execution context in
which the function was created.
The closure is the VARIABLE ENVIRONMENT attached to the function,
exactly as it was at the time and place that the function was
created.
Closure has a priority over scope chain, i.e., if a variable does
not exists in the local scope of a, the function will look for the
variable first in the closure then in the parent scope/s.
IMPORTANT - Closures contains variables from all levels of scope chain.
More examples of closures