Functions Flashcards
Ways to call a function
the 2 you know
Regular Mode: myFunction()
Fucntion as Object Property: myObject.myFunction()
Ways to declare a function
4 ways to declare a non-method function
3 ways to declare a method
(there are more ways)
DECLARATION 1. Regular function declaration function myFunction(variable) { return variable + 2; }
EXPRESSIONS 2. Function expression let myFunction = function(variable) { return variable + 2; }
3. Arrow function let myFunction = variable1 => { return variable + 2; } (with or without parenthesis for 1 variable) or let myFunction = (variable1, variable2) => { return variable + 2;
- anyonymous
(function() {
code
})()
(function() {
code
}) - CREATES THE FUNCTION
() calls it
~~~
METHODS - as a method
let anObject = {
apple: function() {
}
~~~
2. let anObject = { apple() { console.log('yes'); } } 3. let anObject = { apple: x => { console.log('yes'); } }
How to have a default parameter
How does default parameter interact with myFunction.call()?
myFunction(arg = 41)
myFunction.call() doesn’t allow default parameters for some reason.
How do you ask for input:
- in a browser
- in console
let rlSync = require('readline-sync'); let name = rlSync.question("What's your name?\n");
let name = prompt("What's your name?"); console.log(`Good Morning, ${name}`);
Make a random number generator
let randomizer = (min, max) => { return Math.floor(Math.random() * (max - min + 1) + min); }
console.log(randomizer(2,3))
Write a recursive function to return the factorial of the argument
function factorial(number) { if (number === 1) { return 1; }
return number * factorial(number - 1);
}
Write a recursive function to return the Fibonacci sequence of all the numbers smaller than the argument
function fibonacci(number) { if (number < 2) return number; // 0 if number is 0, 1 if number is 1 return fibonacci(number - 1) + fibonacci(number - 2); }
Write a recursive function to make an array of numbers counting down from the argument (2 ways)
console.log(countdown(4)); function countdown(n) { if (n < 0) { return [] } else { let myArray = countdown(n-1); myArray.unshift(n); return myArray; } }
console.log(countdown(4)); function countdown(inputNum) { if (inputNum <= 0) { return [0]; }
return [inputNum, countdown(inputNum - 1)].flat();
}
What is the order of thought to write a recursive function?
Does it hold true for the 3 recursive functions you know?
- Think about what the repeating thing is
- What is the last thing that needs doing?
- What is something that needs doing only once or otherwise considered for?
What does this log? let apple = 5 function boop(input) { console.log(input) input = 2 console.log(input) } boop(apple) console.log(apple)
Why?
5
2
5
Variables as parameters in functions are locally scoped
Can you use a function to change a variable like: let myfunction = variable => { variable = 123; } ?
Can you use a function to change an object?
No when you function AFunction(apple) { apple = 5; } let pear= 1; AFunction(pear); pear; // 1
the function does this:
apple = pear;
With primitives it’s creating a new value.
With objects however, they point to the same object and can be changes
What is a callback function
A callback function is a function passed into another function as an argument
What is alerted? let userName = 'John';
function showMessage() { userName = "Bob";
let message = 'Hello, ' + userName; alert(message); //1 }
alert( userName ); //2
showMessage();
alert( userName ); //3
// John before the function call // Hello Bob // Bob, the value was modified by the function
What is alerted? let userName = 'John';
function showMessage() { let userName = "Bob";
let message = 'Hello, ' + userName; alert(message); }
showMessage(); //1
alert( userName ); //2
// Hello Bob // John, unchanged, the function created a local version of userName and did not access the outer variable
Can you pass a function as a default parameter?
Yes
What are some ways to have a default value in the event a value is created but undefined
(3 ways other than the typical way)
- inside the function write something like:
if (value === undefined) - text ?? ‘empty’
- text || ‘empty’
What happens with "return;": let aFunc = input => { console.log('asfs'); return; } console.log(aFunc('dfs'));
How can this be used?
asfs
undefined
The empty return returns nothing (undefined)
It can be used to “break” from a function (break only works with loops)
for example the alert won’t show below:
function showMovie(age) { if ( !checkAge(age) ) { return; }
alert( "Showing you the movie" ); // (*) // ... }
What happens with this: { return (2 + 4) }
js assumes a ; after return because it’s a new line
It returns undefined
7How should functions be named and created?
3 considerations
- They are actions, they should be verbs:
Function starting with…
“get…” – return a value,
“calc…” – calculate something,
“create…” – create something,
“check…” – check something and return a boolean, etc.
- Then some noun they act upon or create "getForm" "calcPI" "createAddress" "checkDate"
- one action, one function, If you want a function that does multiple things, create multiple functions and another function that calls those functions.
What happens when
myFunction()
is presented like this: myFunction
?
in browser shows the function code.
in visual studio shows the name of the function.
What happens in the numbered steps?
function sayHi() { // (1) create
alert( “Hello” );
}
let func = sayHi; // (2) copy
func(); // Hello // (3) run the copy (it works)! sayHi(); // Hello // this still works too (why wouldn't it)
Did it copy the function or does it point to it?
The Function Declaration
(1) creates the function and puts it into the variable named sayHi.
Line
(2) copies it into the variable func. Please note again: there are no parentheses after sayHi. If there were, then func = sayHi() would write the result of the call sayHi() into func, not the function sayHi itself.
(3) Now the function can be called as both sayHi() and func(). (a pointer like with objects and arrays)
Both just point to it. Functions are not primitive.
Assign a function to another variable
let func = sayHi;
How do you setup a function as an argument?
function aFunc(arg1) { arg1( ); }
How do you pass an anonymous function as an argument?
ask( "Do you agree?", function() { alert("You agreed."); }, function() { alert("You canceled the execution."); });
Difference between function declarations and function expressions availability in code
Function expression not availabe untill assinged to the variable and only after that code
Function declarations are available before where they appear in code because when JavaScript prepares to run the script, it first looks for global Function Declarations in it and creates the functions.
In your own words, describe what a function declaration and function expression and arrow function are
Declaration tells the JavaScript engine about a function's name, return type, and parameters: function aFunc(x, y) { return x + y; }
A function expression allows a function declaration inside an expression. You assign a function to a variable: let aFunc = function(x, y) { return x + y; }
An arrow function is function expression but you don't have to write 'function'. let aFunc = (x, y) => { return x + y; }
What is logged to console: function Func1() { console.log('a'); } let func2 = Func1;
func2();
func2 = function() {
console.log(‘b’);
}
Func1()
func2()
a
a
b
Function variables are pointers like array and object variables.
How can you break from a function?
What does it do?
What happens with "return;": let aFunc = input => { if (x > 2) { return; }
console.log(‘this if not greater than 2’);
}
(returns undefined)
Why does this change userName:
function userNameChanger() { userName = "sally"; }
and this doesn’t?
function userNameChanger(input) { input = "sally"; }
It’s because of the way functions work, and because it’s a primitive value.
userName in the first function references the outer variable by name and changes it.
In the second function, input is a new variable that copies the value of userName.
userName is never changed itself.
This would be different if userName = {name: “Bob”}
Then input would still point to the same object as userName
How do you:
- Have unlimited parameters into a function?
- Access these arguments?
spread operator ... They are input as an array function logSecondArgument(...inputNumbers) { console.log( inputNumbers[2] ); }
How do you make a function an argument?
How do you input a function into another function?
firstfunction (inputFunction, argument) { return inputFunction(argument); }
firstfunction(secondFunction)
EXAMPLE function firstFunction (inputFunction, argument, argument2) { return inputFunction(argument, argument2); }
function adder(num1, num2) { return num1 + num2; }
console.log(firstFunction(adder, 1, 2));
What is the recursive depth limit?
You can rely on it being 10000
```
2019
IE 11: 12,064
Firefox 65: 20,614
Chrome 72: 9,643
Opera 57: 9,638
Safari 12: 32,035
~~~
What happens to the execution context of a function when it recursively calls itself?
One function call has exactly one execution context associated with it.
When a function makes a nested call, the following happens:
The current function is paused.
The execution context associated with it is remembered in a special data structure called execution context stack.
The nested call executes.
After it ends, the old execution context is retrieved from the stack, and the outer function is resumed from where it stopped.
Does recursion or loop based algorithms use more memory?
Recursions use more. They have to store context as the function calls itself.
Any recursion can be rewritten as a loop.
T or F
True
A loop variant of a recursion is just as functional as the recursion
t or f
F
A loop variant can usually be made more effective
Why use recursion over a loop?
Any recursion can be rewritten as a loop. The loop variant usually can be made more effective. The loop variant will use less memory.
…But sometimes the rewrite is non-trivial, especially when function uses different recursive subcalls depending on conditions and merges their results or when the branching is more intricate (getting salaries for all employees with various levels and continued branching of company structure. Need a new loop every time it goes deeper) And the optimization may be unneeded and totally not worth the efforts.
Recursion can give a shorter code, easier to understand and support. Optimizations are not required in every place, mostly we need a good code, that’s why it’s used.
What are the trivial step, halting case, and base of recursion in a recursive function?
The problem that we know the answer to, that can be solved without any more recursive calls
Term for:
The problem that we know the answer to, that can be solved without any more recursive calls (3)
(It’s the easy step)
trivial step,
(It’s the case that ends it)
halting case,
(it’s not a recursive step, it’s the base of all the recursive steps)
and base of recursion
What is the recursive call?
A recursive call is one where procedure A calls itself or calls procedure B which then calls procedure A again
Write a recursive function to add up the salaries of all employees: let company = { sales: [{name: 'John', salary: 1000}, {name: 'Alice', salary: 1600 }], development: { sites: [{name: 'Peter', salary: 2000}, {name: 'Alex', salary: 1800 }], internals: [{name: 'Jack', salary: 1300}] } };
function sumSalaries(department) { if (Array.isArray(department)) { // case (1) return department.reduce((prev, current) => prev + current.salary, 0); } else { // case (2) let sum = 0; for (let subdep of Object.values(department)) { sum += sumSalaries(subdep); } return sum; } }
What is a nested function?
a function declared inside another function aFunction() { function anotherFunction() { } }
What is alerted?
function sayHi() {
alert(“Hi”);
}
alert(sayHi.name);
// sayHi
What does this alert? let sayHi = function() { alert("Hi"); };
alert(sayHi.name);
// sayHi (this is remarkable for some reason) https://javascript.info/function-object
What is alerted?
function f(sayHi = function() {}) {
alert(sayHi.name); // sayHi (works!)
}
f();
// sayHi (unless if you input another function into the equation, then it becomes the other functions name)
What is “contextual name”
If the function does not provide a name, then in an assignment it is figured out from the context.
What is alerted? let user = {
sayHi() { // ... },
sayBye: function() { // ... }
}
alert(user.sayHi.name);
alert(user.sayBye.name);
// sayHi // sayBye
What is alerted? let arr = [function() {}];
alert( arr[0].name );
// (an empty string) // the engine has no way to set up the right name, so there is none
Call a function immediately after creating it
3 ways
Anonymous (function () { //function code })()
Declaration (function apple() { //function code })()
Expression (note the absence of let. It still sets the function to the apple variale)
( apple = function(){
console.log(‘aa’);
})()
what does the length property on a function do?
returns the number of parameters
What is alerted?
function many(a, b, …more) {}
alert(many.length);
// 2
Add a property to a function
function sayHi() { alert("Hi");
// let's count how many times we run sayHi.counter++; } sayHi.counter = 0; // initial value
sayHi(); // Hi
sayHi(); // Hi
alert( Called ${sayHi.counter} times
); // Called 2 times
This returns an error
t or f
let sayHi = function functionName(who) { alert(`Hello, ${who}`); };
False
What’s a named function expression?
let sayHi = function functionName(who) { alert(`Hello, ${who}`); };
What is an NFE?
Named function expression let sayHi = function functionName(who) { alert(`Hello, ${who}`); };
1
How can a named function expression (NFE) be used?
2
Why use it this way?
1. Can input the function into itself BUT that function is not accessible outside the function. let sayHi = function func(who) { if (who) { alert(`Hello, ${who}`); } else { func("Guest"); // use func to re-call itself } };
sayHi(); // Hello, Guest
// But this won't work: func(); // Error, func is not defined (not visible outside of the function)
2. Because the outer name can change let sayHi = function(who) { if (who) { alert(`Hello, ${who}`); } else { sayHi("Guest"); // Error: sayHi is not a function } };
let welcome = sayHi; sayHi = null;
welcome(); // Error, the nested sayHi call doesn’t work any more!
It almost functions as a “this” for functions.
Make a counter function that holds the counter as a a property
function makeCounter() {
function counter() { return counter.count++; }
counter.count = 0;
counter.set = function(setValue) {
return counter.count = setValue;
}
counter.decrease = function() {
return counter.count–;
}
return counter;
}
let apple = makeCounter();
console. log(apple());
console. log(apple());
console. log(apple());
console. log(apple());
console. log(apple.set(111));
console. log(apple.decrease());
console. log(apple.decrease());
console. log(apple.decrease());
console. log(apple.decrease());
console. log(apple.decrease());
Write a function where this works: alert( sum(1)(2) ); // 3 alert( sum(5)(-1)(2) ); // 6 alert( sum(6)(-1)(-2)(-3) ); // 0 alert( sum(0)(1)(2)(3)(4)(5) ); // 15
STEPS
1. create a variable currentSum
2. create a function that will be returned from the outer function that adds a value to currentSum. So when the outer function is called, it will add a value to currentSum.
3. Now we need to be able to display the value. Alerting a function in browser returns a string (this all doesn’t work in vscode where logging a function returns the function code
AND to get an actual value from the function (rather than the function code) you have to control what is returned using toString(). use toString to return the current sum.
4. So when you call sum()()(), it returns a string value, but also calls the function on it.
function sum(a) {
let currentSum = a;
function f(b) { currentSum += b; return f; }
f.toString = function() {
return currentSum;
};
return f;
}
to make it work in vscode:
console. log( String. sum(1)(2) )); // 3
console. log( String. sum(5)(-1)(2) )); // 6
console. log( String. sum(6)(-1)(-2)(-3) )); // 0
console. log( String. sum(0)(1)(2)(3)(4)(5) )); // 15
create a function with the new syntax
let sum = new Function('a', 'b', 'return a + b'); console.log( sum(1, 2) ); // 3
Why ever use “new function” over regular stuff?
Specific cases:
This special feature of new Function looks strange, but appears very useful in practice.
Imagine that we must create a function from a string. The code of that function is not known at the time of writing the script (that’s why we don’t use regular functions), but will be known in the process of execution. We may receive it from the server or from another source.
Our new function needs to interact with the main script.
What if it could access the outer variables?
The problem is that before JavaScript is published to production, it’s compressed using a minifier – a special program that shrinks code by removing extra comments, spaces and – what’s important, renames local variables into shorter ones.
For instance, if a function has let userName, minifier replaces it with let a (or another letter if this one is occupied), and does it everywhere. That’s usually a safe thing to do, because the variable is local, nothing outside the function can access it. And inside the function, minifier replaces every mention of it. Minifiers are smart, they analyze the code structure, so they don’t break anything. They’re not just a dumb find-and-replace.
So if new Function had access to outer variables, it would be unable to find renamed userName.
If new Function had access to outer variables, it would have problems with minifiers.
Besides, such code would be architecturally bad and prone to errors.
To pass something to a function, created as new Function, we should use its arguments.