My professor has given us the following snippet of Javascript which we are supposed to analyze:
function createMultiplyer(multiple) {
n = multiple;
return function(num) {
return num * n;
};
}
var fiveMultiplyer = createMultiplyer(15);
var x = fiveMultiplyer(10);
alert(x);
alert(fiveMultiplyer);
This piece of code outputs an alert containing the text "150" followed by another alert which reads function(num) { return num * n; }. However, I cannot seem to understand why that is the case.
Can someone help me trace through the code and explain what is happening?
1 Let's consider line
var fiveMultiplyer = createMultiplyer(15);
After it, fiveMultiplyer variable will have return value of createMultiplyer function (that's how functions work). And that return value is
function(num) {
return num * n;
};
So, the code is similar to this (about n later)
var fiveMultiplyer = function(num) {
return num * n;
};
2 The next line is
var x = fiveMultiplyer(10);
Here we just invoke the function above. It also uses variable n: that variable is set in createMultiplyer function: n = multiple;. Thus, in our case n is 15 and fiveMultiplyer(10) is equivalent to 10 * 15.
That's all. Hope it helps.
edit
I'll also note that n is a global variable the way it's declared. So, you can access it from anywhere in the code.
var fiveMultiplyer = createMultiplyer(15); // Create a function that multiplies with 15
This function is locally known as fiveMultiplier
var x = fiveMultiplyer(10); // Invoke the multiply-by-15 with argument 10
The result is locally known as x
alert(x); // 150
alert(fiveMultiplyer); // The definition of multiply-by-15 as
// it is returned from createMultiplyer
function createMultiplyer(multiple) { // Returns a new function which
// multiplies with "multiple"
[var] n = multiple; // Note: "var" should have been used to keep "n"
// in scope (within "createMultiplyer").
return function(num) { // Return definition of multiplier function
return num * n; // "num" = arg. when invoked, "n" = multiplier at
// define time (when "createMultiplyer" was called)
};
}
The best way to think of it is as a class or object. var fiveMultiplyer is creating an object that holds a value n = 15 and has a function that accepts a number and multiplies it by n.
In Java this would look something like this
public class Multiplyer {
private int n;
public Multiplyer(int n) {
this->n = n;
}
public int multiple (int m) {
return n*m;
}
}
Multiplyer myMultiplyer = new Multiplyer(15);
System.out.println( myMultiplyer.multiple(10) );
In the JavaScript however the variable fiveMultiplye does not have to call its method, you simple pass it the required variables and it calls the method and returns for you.
Hope that helps.
In JavaScript, you can have a variable which acts as a function too.
var fiveMultiplyer = createMultiplyer(15);
You are calling a CreateMultiplyer(15) function.
This function returns you another function and that is associated
with the fiveMultiplyer var.
var x = fiveMultiplyer(10);
You are actually invoking the function which was returned in previous step.
hence evaluating the value to 10 * 15 = 150
alert(x);
As explained this returns 150
alert(fiveMultiplyer);
As explained this returns the complete function
returned by createMultiplyer().
Related
Here is some code I'm really having issues understanding (JavaScript)
function func(x) {
var y = x + 2;
z = 20;
return function(y) {
var z = y * 3;
return function(z) {
return x + y + z;
};
};
}
console.log(func(3)(4)("z"));
output: 7z
I have a lot of experience with Java (only Java) and I'm really having issues understanding how JavaScript works.
I tried debugging and going step by step over code but I'm still very confused.
One sub-question I have is whether y on line 2 is the same y as in
return function(y) line.
Any help would be greatly appreciated!
When looking for value of variable, JS will pick it from the closest scope going upwards.
In line 5, the y is the y from the argument and not from the upper scope. That value although is enclosed (read closures), is not being used here.
Same, goes for the z below.
When running the statement return x + y + z; the outer scope (that is shadowing the variable y) is destroyed. So the other closes values are used ergo 3 and 4.
function func(x) {
var y = x + 2;
z = 20;
return function(y) {
var z = y * 3;
return function(z) {
return x + y + z;
};
};
}
console.log(func(3)(4)("z"));
Get yourself a good code editor for JS (vscode is great and free)
Go to a variable, press F2 and give it a more unique name.
check which occurrences are affected.
"use strict"! what is Strict Mode?
This is what your code then might look like.
"use strict";
function func(arg0) {
var var1 = arg0 + 2;
// undeclared/global variable
z = 20;
return function (arg2) {
var var2 = arg2 * 3;
return function (arg4) {
return arg0 + arg2 + arg4;
};
};
}
console.log(func(3)(4)("z"));
I think this makes it clearer what variable/parameter is what.
And if you run this, you'll get an error regarding your usage of the undeclared variable z, because strict mode doesn't allow this, whereas sloppy mode would create/use a global variable.
Sidenote: Take a look at Typescript. Coming from such a strict language like Java you might prefer the ability to type your code.
What I understand is from this function call is
fun(3)(4)("Z");
first call
x = 3;
y = 5;
z = 20;
second call
y=4;
z=60;
x=3;
third call
x=3; // from first function parameter
y=4; // y value from second function parameter
z="z" // third function parameter
In the it will return
3+4+"Z" = 7z
as string
All pre calculated values are useless
var is function scope, which means if you redeclare a variable in a function, it will be inside that function. It won’t mutate the outer scopes or global scopes same-named variable.
variableA = 16;
function incrementOne (localVariable) {
var variableA = localVariable + 1;
console.log("variableA internal", variableA);
}
incrementOne(10);
console.log("variableA", variableA);
And my request is not to use any syntax in js like this
variable = 16;
better use var if u really don't want to use let or cons.
var variable = 16
I can assure this that let and const will resolve your maximum understandings. Thanks.
Currently I have a closure in JS that looks like the following:
var addTo = function(num){
var add = function(inner){
return inner + num;
};
return add;
};
var sum = new addTo(1);
My goal is to use the above closure to compute the sum from 1 all the way to 100 (i.e. sum = 1+2+3+...+99+100). Any help? I know a loop is needed, but am unsure of what should go inside the loop and how to use closure to achieve the goal. Thanks guys.
Currently I have a closure in JS that looks like the following:
All functions create closures, they're only remarkable when advantage is taken of them. ;-)
var addTo = function(num){
I don't know why function expressions are used when declarations are clearer (to me):
function addTo(num) {
then there's:
var add = function(inner){
return inner + num;
}
return add;
}
Which (sticking with an expression) can be:
return function (inner) {return inner + num};
}
Then you call it with new:
var sum = new addTo(1);
which causes addTo to create a new object that is not used, so you might as well do:
var sum = addTo(1);
which produces exactly the same result. So:
function addTo(num) {
return function (inner) {return inner + num};
}
var sum = addTo(1);
document.write(sum(3));
However, this is really just a version of Currying, so that sum will just add the supplied value to whatever was initially supplied to addTo.
If you want to add all the numbers from 0 to some limit, you just need a loop, no closure required:
function sumTo(num) {
var total = 0;
for (var i = 0; i <= num; i++) {
total += i;
}
return total;
}
document.write(sumTo(5)); // 15
Note that supplying a negative number will result in an endless loop, you should protect against that (I'll leave it up to you to work out how).
Try
function sum(x) {
var input = x;
function add(y) {
return input + y;
}
return add;
}
//var sum1 = sum(2);
//console.log(sum1(3)); // 5
console.log(sum(2)(3)); //5
Maybe you want to use recursive instead of loops?
function addTo(initial) {
function add(adder) {
if (initial < 100) {
initial+=1
return add(adder+initial)
}
else {
return adder
}
}
return add(initial)
}
document.write(addTo(1))
As long as the initial values don't go over 100, it would just add with sum of all calculation before + itself + 1.
It looks like the addTo() function returns another function into sum that will add whatever you pass it to the original number (or I assume that's what you meant to write; the first thing to do is change the statement inside of add() to use a += instead of just + to make sure you save the result).
Since you want to add each number from 2 to 100 (since you already passed 1 into addTo()), try writing a for loop that runs from 2 to 100 passing each one into the sum() function to add them all together. Here's an example:
var sum = addTo(1);
for (var i=2; i<100; i++) sum(i);
var result = sum(100);
Here I added 100 after the loop since I wanted to grab the final result. You could also add 100 in the loop and use sum(0) to get the result without changing it after the loop.
I am having a little bit of trouble understanding Higher Order Functions in javascript.
Can someone explain to me the difference of what's going on in these two situations?
Scenario 1:
// A function that takes in a number (x) and adds one to it.
function doMath(x){
return function (x){
return x + 1;
}
}
var didMath = doMath(5);
console.log(didMath()); // returns error
var didMath = doMath();
console.log(didMath(5)); // returns 6
var didMath = doMath(100);
console.log(didMath(5)); // still returns 6
Scenario 2:
function doMath2(x,callback){
return callback(x);
}
function add(x){
return x + 1;
}
console.log(doMath2(5,add)); // returns 6, works perfectly fine
I was under the impression that closures have access to parameters from their containing functions. Why is it that in Scenario 1, the "x" param in doMath is not accessible by the contained function?
what is happening here is you are never storing the value of x, you always return a new function, see this example it should work as you expect and maybe helps you to undersant
function doMath(x){
var y = x;
return function(y){
return y + 1;
}
}
In scenario 1
The first one outputs an error because the returned function expects an argument and you don't give one. If you remove the argument it works:
// A function that takes in a number (x) and adds one to it.
function doMath(x){
return function (){ // <--- here
return x + 1;
}
}
var didMath = doMath(5);
console.log(didMath());
In your two other examples you do give an argument and that is the one taken into account. Not the value that you give as parameter to doMath()
I ran this in the console to find the value of result but I am stumped as to why it is 122. I cannot figure why, nor can I figure out how bonus is used in the code blow. Could someone explain the value of bonus and how they attained the values of each variable declared at the beginning please. I think it will help me and the rest of the world understand what's going in this learning script:
var hidden = mystery(3);
var jumble = mystery3(hidden);
var result = jumble(2);
function mystery ( input ){
var secret = 4;
input+=2;
function mystery2 ( multiplier ) {
multiplier *= input;
return secret * multiplier;
}
return mystery2;
}
function mystery3 ( param ){
function mystery4 ( bonus ){
return param(6) + bonus;
}
return mystery4;
}
Thank you very much in advance! (i've reviewed many resources and can't quite figure this rather basic one out). :(
Logging out or even better, writing out the returned values by hand and looking at one statement at a time helps you simplify the problem.
var hidden = mystery(3);
mystery(3) returns the function:
function mystery2 ( multiplier ) {
multiplier *= input; //notice input is 5
return secret * multiplier; // and secret is 4
}
Note that input and secret in this case will always be constant. This is not always the case though. Normally the reason why closure is used is to encapsulate variables in a private environment and the closure functions provide a way for non-local function to "reach" into the private scope. Those variables are not garbage collected after the function has finished executing because the returned functions still have access to them. Those function can still change the value of the variables inside the function even after the function has already ended.
var jumble = mystery3(hidden);
mystery3(hidden) returns the function:
function mystery4 ( bonus ){
return param(6) + bonus; //param(6), which points to mystery2 above,
// is just 6*5*4 = 120
}
var result = jumble(2);
Well, jumble(2), which "is" mystery4 above, is just 120 + 2 thus 122.
Well that's a pretty convoluted set of functions, but...
You can think of var hidden = mystery(3) as:
function mystery2( multiplier ) {
multiplier *= 5;
return 4 * multiplier;
}
Then, you can think of var jumble = mystery3(hidden) as:
function mystery4( bonus ){
return mystery2(6) + bonus;
}
...or
function mystery4(bonus) {
return 120 + bonus; // 120 is the result of 6 * 5 * 4
}
And then when you call jumble(2) it calls mystery(bonus) which does return 120 + bonus, or return 120 + 2;
I'm reading this book: http://eloquentjavascript.net/ which I think is brilliant.
However I'm having difficulty understanding the following function, where does the function add(number) get its argument from?
function makeAddFunction(amount) {
function add(number) {
return number + amount;
}
return add;
}
var addTwo = makeAddFunction(2);
var addFive = makeAddFunction(5);
show(addTwo(1) + addFive(1)); // gives 9
I thought the answer would be 7 to this show(addTwo(1) + addFive(1));
In makeAddFunction(2), amount is 2, but what would number be? so number + 2...
NB: show function is pretty much echo in php.
makeAddFunction returns a new function. The new function takes a param, number, and adds it to whatever was originally given to makeAddFunction.
var addTwo = makeAddFunction(2);
// addTwo is now a function which you can call with a numeric argument ('number')
// anything you pass to it will have two added to it
var five = addTwo( 3 ); // add two to three (makes five)
See JAAulde's answer for what makeAddFunction's purpose is, which was really the main question, imo
The answer to your second question is, you generate two functions. They look like this (basically):
var addTwo = function add(number) {
return number + 2;
};
var addFive = function add(number) {
return number + 5;
};
It should be obvious why you get:
addTwo(1) + addFive(1)
(1 + 2) + (1 + 5) = 9 now.
What would number be? Number is an argument to the returned function. I think you're thinking about this too hard.
makeAddFunction(5) effectively returns a named reference to function(number) { return number + 5; }