Working with Functions Flashcards

1
Q

What is a function?

A

Generally speaking, a function is a “subprogram” that can be called by code external (or internal, in the case of recursion) to the function. Like the program itself, a function is composed of a sequence of statements called the function body. Values can be passed to a function as parameters, and the function will return a value.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

Why are functions first class objects in JavaScript?

A

A programming language is said to have First-class functions when functions in that language are treated like any other variable. For example, in such a language, a function can be passed as an argument to other functions, can be returned by another function and can be assigned as a value to a variable.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

What is a function declaration?

A

A function definition (also called a function declaration, or function statement) consists of the function keyword, followed by:

  • The name of the function.
  • A list of parameters to the function, enclosed in parentheses and separated by commas.
  • The JavaScript statements that define the function, enclosed in curly brackets, { /* … */ }.

Example:

function square(number) {
  return number * number;
}
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

What is a function expression?

A

A function expression is a function defined within an expression.

Example:

const getRectArea = function (width, height) {
  return width * height;
};

console.log(getRectArea(3, 4));
// Expected output: 12
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

How is a function called in JavaScript?

A

A function is called by its name, followed by parentheses with possible parameters. Example: functionName(parameters);.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

What is a recursive function in JavaScript?

A

A recursive function in JavaScript is a function that calls itself to solve a problem. An example of this is a function that calculates the factorial of a number.

function factorial(n) {
  if (n === 0 || n === 1) {
    return 1;
  } else {
    return n * factorial(n - 1);
  }
}

You could then compute the factorials of 1 through 5 as follows:

console.log(factorial(1)); // 1
console.log(factorial(2)); // 2
console.log(factorial(3)); // 6
console.log(factorial(4)); // 24
console.log(factorial(5)); // 120
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

What is function hoisting in JavaScript?

A

Hoisting is JavaScript’s behavior of moving declarations to the top. In the context of functions, even if a function is declared after its call in the code, JavaScript will move the function declaration to the top, so it can be called before its declaration.

Consider the example below:

console.log(square(5)); // 25

function square(n) {
  return n * n;
}

This code runs without any error, despite the square() function being called before it’s declared. This is because the JavaScript interpreter hoists the entire function declaration to the top of the current scope, so the code above is equivalent to:

// All function declarations are effectively at the top of the scope
function square(n) {
  return n * n;
}

console.log(square(5)); // 25
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

Does function hoisting work with function expressions in JavaScript?

A

No, function hoisting only works with function declarations — not with function expressions. The following code will not work:

console.log(square(5)); // ReferenceError: Cannot access 'square' before initialization
const square = function (n) {
  return n * n;
};
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

Explain function scope

A

Variables defined inside a function cannot be accessed from anywhere outside the function, because the variable is defined only in the scope of the function. However, a function can access all variables and functions defined inside the scope in which it is defined.

For example, a function defined in the global scope can access all variables defined in the global scope. A function defined inside another function can also access all variables defined in its parent function, and any other variables to which the parent function has access.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

What is a recursive function?

A

A function that calls itself is called a recursive function.

“Recursion” (developer.mozilla.org). Retrieved September 6, 2023.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

How can a function call itself?

A

A function can refer to and call itself using one of the following:

  1. The function’s name
  2. arguments.callee()
  3. An in-scope variable that refers to the function

For example, consider the following function definition:

const foo = function bar() {
  // statements go here
};

Within the function body, the following are all equivalent:

  1. bar()
  2. arguments.callee()
  3. foo()

“Recursion” (developer.mozilla.org). Retrieved September 6, 2023.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

What is the call stack?

A

A call stack is a mechanism for an interpreter to keep track of its place in a script that calls multiple functions — what function is currently being run and what functions are called from within that function, etc.

  • When a script calls a function, the interpreter adds it to the call stack and then starts carrying out the function.
  • Any functions that are called by that function are added to the call stack further up, and run where their calls are reached.
  • When the current function is finished, the interpreter takes it off the stack and resumes execution where it left off in the last code listing.
  • If the stack takes up more space than it was assigned, a “stack overflow” error is thrown.

Note: The call stack is also called function stack in some places.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

Properties of nested functions and closures

A
  • The inner function can be accessed only from statements in the outer function.
  • The inner function forms a closure: the inner function can use the arguments and variables of the outer function, while the outer function cannot use the arguments and variables of the inner function.

Since the inner function forms a closure, you can call the outer function and specify arguments for both the outer and inner function:

function outside(x) {
  function inside(y) {
    return x + y;
  }
  return inside;
}

const fnInside = outside(3); // Think of it like: give me a function that adds 3 to whatever you give it
console.log(fnInside(5)); // 8
console.log(outside(3)(5)); // 8
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

Explain clojures

A

In JavaScript, a closure is a fundamental concept that has to do with how functions and their lexical environments work. Let’s break down the components and principles of a JavaScript closure:

  1. Function Scope: In JavaScript, each function has its own scope. Variables declared within a function are only accessible within that function, and they are not visible to the outside world.
  2. Lexical Scope: JavaScript uses lexical scoping, which means that a function’s scope is determined by its location in the source code when it’s defined. This is also referred to as “static scope.”
  3. Nested Functions: You can define functions inside other functions. When you do this, the inner function has access to the variables and parameters of the outer (enclosing) function. This forms a closure.

“Closures” (developer.mozilla.org). Retrieved September 11, 2023.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

What is the arguments object of a function?

A

The arguments of a function are maintained in an array-like object. Within a function, you can address the arguments passed to it as follows:

arguments[i];

where i is the ordinal number of the argument, starting at 0. So, the first argument passed to a function would be arguments[0]. The total number of arguments is indicated by arguments.length.

Using the arguments object, you can call a function with more arguments than it is formally declared to accept. This is often useful if you don’t know in advance how many arguments will be passed to the function. You can use arguments.length to determine the number of arguments actually passed to the function, and then access each argument using the arguments object.

Note: The arguments variable is “array-like”, but not an array. It is array-like in that it has a numbered index and a length property. However, it does not possess all of the array-manipulation methods.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

How do you set default parameters in JavaScript?

A

In JavaScript, parameters of functions default to undefined. However you can set default parameters with the equal operator =.

Examples:

function multiply(a, b = 1) {
  return a * b;
}

console.log(multiply(5)); // 5
17
Q

What are rest parameters?

A

The rest parameter syntax allows a function to accept an indefinite number of arguments as an array, providing a way to represent variadic functions in JavaScript.

Syntax

function f(a, b, ...theArgs) {
  // …
}

A function definition’s last parameter can be prefixed with ... (three U+002E FULL STOP characters), which will cause all remaining (user supplied) parameters to be placed within an Array object.

18
Q

What is The difference between rest parameters and the arguments object?

A

There are four main differences between rest parameters and the arguments object:

  • The arguments object is not a real array, while rest parameters are Array instances, meaning methods like sort(), map(), forEach() or pop() can be applied on it directly.
  • The arguments object has the additional (deprecated) callee property.
  • In a non-strict function with simple parameters, the arguments object syncs its indices with the values of parameters. The rest parameter array never updates its value when the named parameters are re-assigned.
  • The rest parameter bundles all the extra parameters into a single array, but does not contain any named argument defined before the ...restParam. The arguments object contains all of the parameters — including the parameters in the ...restParam array — bundled into one array-like object.
19
Q

What is the problem witht he arguments object on non-strict functions?

A

Non-strict functions that only has simple parameters (that is, no rest, default, or destructured parameters) will sync the new value of parameters with the arguments object, and vice versa:

function func(a) {
  arguments[0] = 99; // updating arguments[0] also updates a
  console.log(a);
}
func(10); // 99

function func2(a) {
  a = 99; // updating a also updates arguments[0]
  console.log(arguments[0]);
}
func2(10); // 99
20
Q

What happens to the arguments object on non-strict function if it has non simple parameters like rest parameter, default or destructured parameters?

A

arguments object will not sync and wil exhibit same behavior exhibited by all strict-mode functions, regardless of the type of parameters they are passed. That is, assigning new values to parameters in the body of the function never affects the arguments object, nor will assigning new values to the arguments indices affect the value of parameters, even when the function only has simple parameters.

function funcWithDefault(a = 55) {
  arguments[0] = 99; // updating arguments[0] does not also update a
  console.log(a);
}
funcWithDefault(10); // 10

function funcWithDefault2(a = 55) {
  a = 99; // updating a does not also update arguments[0]
  console.log(arguments[0]);
}
funcWithDefault2(10); // 10

// An untracked default parameter
function funcWithDefault3(a = 55) {
  console.log(arguments[0]);
  console.log(arguments.length);
}
funcWithDefault3(); // undefined; 0
21
Q

What does it mean that the arguments object is an array-like object and not an Array?

A

arguments is an array-like object, which means that arguments has a length property and properties indexed from zero, but it doesn’t have Array’s built-in methods like forEach() or map(). However, it can be converted to a real Array, using one of slice(), Array.from(), or spread syntax.

const args = Array.prototype.slice.call(arguments);
// or
const args = Array.from(arguments);
// or
const args = [...arguments];
22
Q

What are the properties of the arguments object?

A
  • arguments.callee - Deprecated - Reference to the currently executing function that the arguments belong to. Forbidden in strict mode.
  • arguments.length - The number of arguments that were passed to the function.
  • arguments[@@iterator] - Returns a new Array iterator object that contains the values for each index in arguments.
23
Q

What is a method?

A

A method is a function which is a property of an object. There are two kinds of methods: instance methods which are built-in tasks performed by an object instance, or static methods which are tasks that are called directly on an object constructor.

24
Q

What is an arrow function?

A

An arrow function expression (also called a fat arrow to distinguish from a hypothetical -> syntax in future JavaScript) has a shorter syntax compared to function expressions and does not have its own this, arguments, super, or new.target. Arrow functions are always anonymous.

25
Q

What are the properties of arrow functions?

A

An arrow function expression is a compact alternative to a traditional function expression, with some semantic differences and deliberate limitations in usage:

26
Q

What is the syntax of arrow functions?

A
() => expression

param => expression

(param) => expression

(param1, paramN) => expression

() => {
  statements
}

param => {
  statements
}

(param1, paramN) => {
  statements
}
27
Q

What does it mean that arrow functions have no binding to this?

A

Until arrow functions, every new function defined its own this value (a new object in the case of a constructor, undefined in strict mode function calls, the base object if the function is called as an “object method”, etc.). This proved to be less than ideal with an object-oriented style of programming.

function Person() {
  // The Person() constructor defines `this` as itself.
  this.age = 0;

  setInterval(function growUp() {
    // In nonstrict mode, the growUp() function defines `this`
    // as the global object, which is different from the `this`
    // defined by the Person() constructor.
    this.age++;
  }, 1000);
}

const p = new Person();

An arrow function does not have its own this; the this value of the enclosing execution context is used. Thus, in the following code, the this within the function that is passed to setInterval has the same value as this in the enclosing function:

function Person() {
  this.age = 0;

  setInterval(() => {
    this.age++; // `this` properly refers to the person object
  }, 1000);
}

const p = new Person();