0% found this document useful (0 votes)
6 views

2 - Functions As First-Class Objects

Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
6 views

2 - Functions As First-Class Objects

Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 29

Functions

are fundamental
Introduction
• In JavaScript, functions are first-class objects, or first-class
citizens.
• They coexist with, and can be treated like, any other JavaScript
object.
• They can be referenced by variables, declared with literals, and
even passed as function parameters.
• Functions are primary modular units of execution.
• Except for the global JavaScript code executed in the page-
building phase, all of the script code that we’ll write for our pages
will be within a function.

2
The Deal with Objects
• First, let’s see some of the operations we can use with objects.
• In JavaScript, objects enjoy certain capabilities:
1. Objects can be created via literals: {}
2. They can be assigned to variables, array entries, and properties
of other objects:
var obj = {}; //Assigns a new object to a variable
objArr.push({});//Adds a new object to an array
obj.data = {};//Assigns a new object as a
property of another object
3. They can be passed as arguments to functions:
function hide(obj){
obj.visibility = false;
}
hide({});

3
The Deal with Objects
4. They can be returned as values from functions:
function returnNewobj() {
return {};
}

5. They can possess properties that can be dynamically created and


assigned:
var obj = {};
obj.name = "Hanzo";

Unlike in many other programming languages, in JavaScript we


can do almost the exact same things with functions also.

4
Functions as First-class Objects
1. Created via literals
function newFunction() {}
2. Assigned to variables, array entries, and properties of other
objects

var varFunction = function() {};


fnArray.push(function(){});
obj.data = function(){};

3. Passed as arguments to other functions


function call(myFunction){
myFunction();
}
call(function(){});

5
Functions as First-class Objects
4. Returned as values from functions
function returnNewFunction() {
return function(){};
}

5. They can possess properties that can be dynamically created and


assigned:

var myFunction = function(){};


myFunction.name = "Hanzo";

• Functions are objects, just with an additional, special


capability of being invokable: Functions can be called or
invoked in order to perform an action.

6
Callback Functions
• Functions can be passed to functions as arguments.
• We pass a function as an argument to another function that
might, at a later point in application execution, call the passed-in
function.
• This is an example of a more general concept known as a
callback function.
• The term stems from the fact that we’re establishing a function
that other code will later “call back” at an appropriate point of
execution.
function useless(Callbackfn) {
return Callbackfn();
}

7
Callback Functions

var text = "Hello World!";


console.log("Before defining functions");
function useless(Callbackfn) {
console.log("In useless function");
return Callbackfn();
}
function getText() {
console.log("In getText function");
return text;
}
console.log("Before making all the calls");
console.log(useless(getText));
console.log("After the calls have been made");

8
Callback Functions
• Another way to write the same code:

var text = "Hello World!";


function useless(Callbackfn) {
return Callbackfn();
}
console.log(useless(function () { return text;}));
console.log("After the calls have been made");

• With JS, we can create functions in the code anywhere an


expression can appear.
• Benefits:
§ makes the code more compact and easier to understand.
§ eliminates the need to pollute the global namespace with
unnecessary names.
9
Functions as Objects
• We can attach properties to functions:
var course = {};
course.name = “Application of Web Development";
var CourseCode = function(){};
CourseCode.name = “CCE421";

• More interesting features:


§ Storing functions in a collection allows us to easily manage
related functions—for example, callbacks that have to be
invoked when something of interest occurs.
§ Memoization allows the function to remember previously
computed values, thereby improving the performance of
subsequent invocations.

10
Storing Functions
• In certain cases, we want to store collections of unique functions.
• For example, when we need to manage collections of callbacks
that should be invoked when a certain event occurs.
var store = {
nextId: 1,
cache: {},
add: function(fn) {
if (!fn.id) {
fn.id = this.nextId++;
this.cache[fn.id] = fn;
return true;
}
}
};
function ninja(){}
if(store.add(ninja)){console.log("Function was safely
added.");}
if(!store.add(ninja)){console.log("But it was only added
once.");}
11
Self-memoizing Functions
• When using function properties, we can give a function the ability
to modify itself.
• This technique can be used to remember previously computed
values, saving time during future computations.
• Memoization: the process of building a function that’s capable
of remembering its previously computed values.
• Whenever a function computes its result, we store that result
alongside the function arguments.
• In this way, when another invocation occurs for the same set of
arguments, we can return the previously stored result, instead of
calculating it anew.
• This can markedly increase performance by avoiding needless
complex computations that have already been performed.

12
Self-memoizing Functions
• Within the isPrime function, we start by checking whether the answers
property that we’ll use as a cache.
• Within this cache, we’ll store the computed answer (true or false) using
the argument value as the property key. If we find a cached answer, we
return it.
function isPrime(value){
if (!isPrime.answers){ isPrime.answers = {}; }
if (isPrime.answers[value] !== undefined) {
return isPrime.answers[value]; }
var prime = value !== 1; // 1 is not a prime
for (var i = 2; i < value; i++) {
if (value % i === 0) {
prime = false;
break;
}
}
return isPrime.answers[value] = prime;
}
assert(isPrime(5), "5 is prime!" );
assert(isPrime.answers[5], "The answer was cached!" ); 13
Self-memoizing Functions
• This approach has two major advantages:
1. The end user enjoys performance benefits for function calls asking
for a previously computed value.
2. It happens seamlessly and behind the scenes; neither the end user
nor the page author needs to perform any special requests or do
any extra initialization in order to make it all work.
• Also, its disadvantages may need to be weighed against its advantages:
1. Any sort of caching will certainly sacrifice memory in favor of
performance.
2. Purists may consider that caching is a concern that shouldn’t be
mixed with the business logic; a function or a method should do
one thing and do it well.
3. It’s difficult to load-test or measure the performance of an
algorithm such as this one, because our results depend on the
previous inputs to the function.
14
Defining functions
• Functions are declared with the function keyword.
• JavaScript provides a couple of ways to define functions:

Function declarations and


function expressions
The two most common different Function constructors
ways of defining functions. A not-so-often used way of
defining functions.

Arrow functions Generator functions


A recent, ES6 addition to the This ES6 addition to JavaScript
JavaScript standard that enables us to define enable us to create functions that
functions with far less syntactic can be exited and reentered later
clutter. in the
application execution, while
keeping the values of their
variables across these
re-entrances

15
Function Declarations and Function Expressions
• Function declarations:

• A function declaration must be placed on its own, as a separate


JavaScript statement, but can be contained within another function or
a block of code.

16
Function Declarations and Function Expressions
• Function declarations:
function samurai() {
return "samurai here";
}
function ninja() {
function hiddenNinja() {
return "ninja here";
}
return hiddenNinja();
}

• If you haven’t had much exposure to functional languages: this is a


function defined within another function!

17
Function Declarations and Function Expressions
• Function expressions:
• Because functions are such fundamental constructs, JavaScript
enables us to treat them as any other expressions.
• So, just as we can use number literals, for example

var a = function() {};


myFunction(function(){});

• Such functions that are always a part of another statement (for


example, as the right side of an assignment expression, or as an
argument to another function) are called function expressions.
• Function expressions are great because they allow us to define
functions exactly where we need them, in the process making our code
easier to understand.

18
Function Declarations and Function Expressions
• The function name is optional.

function myFunctionDeclaration(){ //function declarations


function innerFunction() {}
}
var myFunc = function(){}; // on the expression level
myFunc(function(){ //Or as an argument to a function call
return function(){}; //or as a function return value
});
(function namedFunctionExpression () {
})(); //Named function expression as
part of a function call that will
be immediately invoked
+function(){}(); // Function expressions
-function(){}(); that will be immediately
!function(){}(); invoked, as arguments
~function(){}(); to unary operators

19
Function Declarations and Function Expressions
• Function declarations must have a name defined because they stand
on their own.
• Because one of the basic requirements for a function is that it has to be
invokable, we have to have a way to reference it, and the only way to
do this is through its name.
• Function expressions, on the other hand, are parts of other JavaScript
expressions, so we have alternative ways to invoke them.
• For example, if a function expression is assigned to a variable, we can
use that variable to invoke the function:
var doNothing = function(){};
doNothing();

function doSomething(action) {
action();
}

20
Immediate Functions

(function(){})(3);

• When we want to make a function call, we use an expression that


evaluates to a function, followed by a pair of function call
parentheses, which might contain arguments.
• A simple way to specify an expression that evaluates to a function is to
use a function expression.
• So, in the code above, we first create a function, and then we
immediately invoke that newly created function.
• This, is called an immediately invoked function expression (IIFE), or
immediate function for short.
• We place the function expression within parentheses to inform the
JavaScript parser that it’s dealing with an expression, and not a
statement.

21
Arrow Functions
• Arrow functions are a simplification of function expressions.

var greet = name => "Greetings " + name;


var anotherGreet = function(name){
return "Greetings " + name;
};

22
Arrow Functions
• Arrow functions are a simplification of function expressions.

23
Arrow Functions
• The arrow function definition starts with an optional comma-separated
list of parameter names.
• If there are no parameters, or more than one parameter, this list must
be enclosed within parentheses.
• But if we have only a single parameter, the parentheses are optional.
• This list of parameters is followed by a mandatory fat-arrow operator,
which tells us and the JavaScript engine that we’re dealing with an
arrow function.
• After the fat-arrow operator, we have two options. If it’s a simple
function, we put an expression there (a mathematical operation,
another function invocation, whatever), and the result of the function
invocation will be the value of that expression.
• For instance, our first arrow function example has the following arrow
function:
var greet = name => "Greetings " + name;
24
Arrow Functions
• In other cases, when our arrow functions aren’t that simple and require
more code, we can include a block of code after the arrow operator. For
example:
var greet = name => {
var helloString = 'Greetings ‘;
return helloString + name;
};

25
Arguments and Function Parameters
• When discussing functions, we often use the terms argument and
parameter almost interchangeably, as if they were more or less the
same thing. But now, let’s be more formal:
§ A parameter is a variable that we list as part of a function definition.
§ An argument is a value that we pass to the function when we invoke it.

function skulk(ninja) { Parameter


return performAction(ninja, "skulking"); Arguement
}

• When a list of arguments is supplied as a part of a function invocation,


these arguments are assigned to the parameters in the function
definition in the order specified.
• The first argument gets assigned to the first parameter, the second
argument to the second parameter, and so on.

26
Arguments and Function Parameters
• If we have a different number of arguments than parameters, no error
is raised.
• JavaScript is perfectly fine with this situation and deals with it in the
following way:

27
Default parameters
• Default parameters enable us to specify default parameter values that
will be used if no value is supplied during function invocation
• In other programming languages, this problem is most often solved
with function overloading (specifying additional functions with the
same name but a different set of parameters).
• Unfortunately, JavaScript doesn’t support function overloading.
• To get around this problem, JS offers default parameters:
function performAction(student, action = “studying"){
return student + " " + action;
}
performAction(“Ahmed")
• We can assign any values to default parameters: simple, primitive
values such as numbers or strings, but also complex types such as
objects, arrays, and even functions.

28
Default parameters
• The values are evaluated on each function call, from left to right, and
when assigning values to later default parameters, we can reference
previous parameters, as in the following:

function performAction(student, action = “studying",


message = student + " " + action) {
return message;
}

• Even though JavaScript allows you to do something like this, we urge


caution.
• In our opinion, this doesn’t enhance code readability and should be
avoided, whenever possible.
• But moderate use of default parameters—as a means of avoiding null
values, or as relatively simple flags that configure the behaviors of our
functions—can lead to much simpler and more elegant code.

29

You might also like