Functions in Javascript — Part 2

Sunilkathuria
In Computing World
Published in
6 min readFeb 20, 2024

We learned the following points from the previous article (Functions in JavaScript — Part -1).

How to create and use functions — and the rules about parameters and return values.

Differentiation between pass-by-value and pass-by-reference.

The return value of a function.

In this article, we will learn about the scoping rules. Get a little deeper into the pass-by-value and pass-by-reference concept. Finally, explain the idea of a function being a first-class object.

Variable scoping — the game of hide and seek

Understanding the scoping of variables is very important in writing clean and maintainable code. When a script executes, the scope helps in understanding which values or variables are visible (accessible) and which all are not visible. JavaScript provides the following types of scopes.

Global Scope

This scope is of the JavaScript runtime. This is available before any script is loaded for execution.

Local Scope

This scope refers to the scope of the script/module currently running. All the variables and functions defined in the script are available under this scope.*

Function Scope

This refers to the scope available at the function level. Variables defined within a function are available at this scope.*

Block Scope

A block is a line(s) of code defined within two curly braces {}. Variables defined within a block are available at this scope.*

*Note: If a variable is defined without using any of the keywords “let”, “var”, or “const”, then it is available at the global scope.

Following is the debugger snapshot of the variables

Scope chain

In the above example, the variable “x when referred to within the block, the runtime environment looks for its definition within the block. If it is not found, it searches for the same at the function level (it is a local scope here). Since it is unavailable at the function level, it continues searching local scope and displays the value.

Had it not been available at the local scope, the search would have continued to a global level. Finally, the JavaScript runtime will throw an error if the variable is not found globally.

Pass by Value / Reference. Dip in the shallows.

In JavaScript, when a regular data type variable (numbers, Boolean, string) is created, its values are stored in the stack.

An object data type (array, date, or any user-defined object) is created on the heap, and its reference (address of the object) is maintained on the stack. Any update of an attribute of an object changes the original object.

When an argument is passed to a function, it is passed by value. This means the function will maintain a separate copy of the argument. Any change in the argument’s value will not be available outside the function.

Function as First-class citizen

In JavaScript, the functions are treated as first-class citizens. This means a function…

It can be passed as a parameter to a function.

It can be returned from a function.

It can be assigned to a variable.

It can be tested for equality.

The function assigned to a variable

Output

The code snippet function is assigned to a variable “multiply”.

Note that the assignment is done without the braces (). This indicates JavaScript runtime to assign the function object’s address to the variable “multiply”.

When braces () are mentioned along with a function name, this indicates to JavaScript runtime to execute a function and then assign the result of the function to a variable.

Function tested for equality

To test for equality, as per the above code snippet, one can test both “multiply” and “product” using the operator “==” or “===”. In either case, the result will be True. This indicates that “multiply” and “product” are the same function.
In case both “multiply” and “product” have their identical function definition, in this case the comparison operators will yield False. Refer to the code below.

A function is passed as a parameter to a function.

Being a first-class citizen, a function can be passed to another (outer) function as a parameter. This outer function then calls this function to complete a task. The following code snippet explains the same.

Returning a function from a function

A function (let’s call it an outer function) in JavaScript can return a reference to a function that is created within the outer function.

When the outer function is executed, it returns the reference of the inner function. This returned reference is then used to run the inner function.

Note: although the outer function has stopped execution, the context of the inner function still exists.

Concept of Closure

One exciting part is that whenever a function (outer) creates a new function (inner) within itself, the inner function has access to all the variables created locally in the outer function. JavaScript maintains this association using a “closure”.

JavaScript ensures this “closure” is available whenever the inner function executes.

Output

Note: Not only does this closure provide access to the outer variables, but also, maintains the state of these variables among function calls.

In case you are not aware…

Hoisting is a mechanism where JavaScript, at the time of code compilation, moves the definition of variables and functions to the top. With this, any reference to a variable or a function before its declaration does not lead to an error.

This hoisting of a variable is only possible when it is declared with the keyword “var”. The vaule of the variable till it is initialized is set to “undefined”. Otherwise, it is mandatory to declare a variable before referencing it.

In the case of a function, hoisting is possible only when a function is defined as a named function.

Conclusion

· In this article, we learned about different types of variable scoping. Understood how a variable declaration affects scoping.

· Learned about the scoping chain and how a variable is looked for at different levels before JavaScript throws an error.

· Finally, about the functions being first-class-object, how a function is used as a variable — passed as a parameter, tested for equality, assigned to a variable and returned from a function and how the concept of closure works.

References

--

--