Javascript Memoization Explanation? - javascript

Reading an example from a book, can someone explain how the function call to fibonacci takes in the argument 'i' when the function itself doesn't declare any parameters?
var fibonacci = (function () {
var memo = [0, 1];
var fib = function (n) {
var result = memo[n];
if (typeof result !== 'number') {
result = fib(n - 1) + fib(n - 2);
memo[n] = result;
}
return result;
};
return fib;
}());
for(var i = 0; i <= 10; i += 1) {
document.writeln('// ' + i + ': ' + fibonacci(i));
}

You are creating a self-executing anonymous function (function(){}()); which inside it returns the fib function, which takes an argument. var fib = function(n){} ... return fib;
var fibonacci = (function () { // Self-executing anonymous function
var memo = [0, 1]; // local variable within anonymous function
var fib = function (n) { // actual fib function (takes one argument)
var result = memo[n];
if (typeof result !== 'number') {
result = fib(n - 1) + fib(n - 2);
memo[n] = result;
}
return result;
};
return fib; // return fib (fibonacci is now set to the function fib defined above, which takes one argument)
}());
This system (returning a function from a self-executing anonymous function) allows for you to define variable in a local scope that can still be used by the returned function, but not by functions outside the scope. Here is an example.
This technique is called closure in JavaScript. Read more about it on the MDN guide.

Because the function returns a function that does take a parameter.

To understand this, I think it is helpful to work with a simpler example. Take a look at the two memoized functions below. The only difference is the () after add : function (){ ... }() on the successful memorization code.
var failed_memoization = {
add : function (){
var counter;
return function(number){
if(counter){
counter = counter + number;
return counter;
}
counter = number;
return counter;
} //NOTE: NO function call brackets here
}
}
var successful_memoization = {
add : function (){
var counter;
return function(number){
if(counter){
counter = counter + number;
return counter;
}
counter = number;
return counter;
}
}() //NOTE: the function call brackets here!!
};
}
Now let's execute these two functions.
console.log('Failed Memoization');
console.log(failed_memoization.add(5)); //We wanted 5, but this prints the text of the function instead.... Okay, lets try something else
console.log(failed_memoization.add()(5)); //5
console.log(failed_memoization.add()(10)); //10 (Wanted it to be 5+10 = 15.
console.log('successful_memoization');
console.log(successful_memoization.add(8)); //8
console.log(successful_memoization.add(16)); //24 (This is what we wanted 8 + 16 = 24)
So what's going on here is that for successful_memoization when we put () to the end of its add : function(){...}(). As such, this function is executed immediately on the creation of the static object. In turn, executing that function returns the object function (number){...} wich results in the assignment: add : function (number){...} NOT add : function(){} as it initially appears.
What is also important to note is that var counter is declared outside return function(name){}. As it is still being used within add : function(number){...}, this variable is accessible within that function. For failed_memoization.add()(number), it uses a new counter each time we execute that function, because we execute the first function, and then the inner function on each call. For successful_memoization.add(number) we executed the outer function upon initialization, and so counter will persist through all subsequent calls and will not be overwritten.

There is a self-calling function that returns the function with the identifier fib which is then assigned to the identifier fibonacci. This way you can create a private variable memo which is only accessible by the function. So var fibonacci in fact is function(n){...}.

var fibonacci = (function() {
...
return fib;
})();
This is a self-executing function.
It declares a function expression which returns a function (fib), executes the outer function expression immediately (()), and assigns its return value (which is fib) to the fibonacci variable.

Function fibonacci does take one argument. Note that the unnamed function that starts on the first line is not the function that ends up being known as fibonacci. That unnamed function is immediately called since you have () immediately after closing brace }. This unnamed function returns fib, a local variable to which a single-argument function is assigned. Thus, fibonacci ends up referring to the function returned by the unnamed function, i.e. fibonacci is this:
var fib = function (n) {
var result = memo[n];
if (typeof result !== 'number') {
result = fib(n - 1) + fib(n - 2);
memo[n] = result;
}
return result;
};
Note that this function refers to local variables of the unnamed function for the purpose of memoizing.
The critical thing to notice was () which calls the unnamed function immediately, here are some examples that illustrate this technique:
var a = (function() { return 1; });
Variable a holds a function which returns 1.
var a = (function() { return 1; }());
Here however, variable a holds value 1.

Related

Can you explain the order of execution in the code mentioned below?

function makeMultiplier (multiplier){
var myFunc = function (x){
return multiplier * x;
}
return myFunc;
}
var multiplyBy3 = makeMultiplier(3);
console.log(makeMultiplier(3)(10));
Here, I don't understand why and how does the var multiplyBy3 variable acts as a reference to the myFunc function mentioned above
The return value of executing the function makeMultiplier is function myFunc. This is being assigned to variable multiplyBy3 . Hence it will act as a reference to myFunc function
Order of execution:
makeMultiplier is defined
makeMultiplier is called with arg 3 and returns a new function and that returned function is stored in a variable named multiplyBy3.
console log called with makeMultiplier is called with 3, returns a new function and it is called with argument 10
In JavaScript all the non primitive objects' assignments are stored as reference, but not as value. Example variable assignments, argument passing to functions where it basically assigned to the parameter which is a local variable inside the function.
However, second call to the multiplier with arg 3 is a different function, the references are different.
Also you can test those with Object.is() static method.
In your code, you don't actually use multiplyBy3, but here's your code modified to use it as the reference to the inner myFunc(3):
function makeMultiplier(multiplier) {
var myFunc = function(x) {
return multiplier * x;
}
return myFunc;
}
var multiplyBy3 = makeMultiplier(3);
console.log(multiplyBy3(10));
When setting the multiplyBy3 variable, we call the makeMultiplier function with 3 as our multiplier argument. This returns a reference to function(x) { return 3 * x; } which is assigned to multiplyBy3.
Calling multiplyBy3(10) then results in the value of 30 due to multiplying 3 by the argument of 10. This is equivalent to your original code makeMultiplier(3)(10)
In the following code snippet, I modified your code to use multiplyBy3 and threw in some console.log statements to show the steps taken both outside and inside the functions.
function makeMultiplier(multiplier) {
console.log("[enter] makeMultiplier");
var myFunc = function(x) {
console.log("[enter] myFunc");
return multiplier * x;
}
return myFunc;
}
console.log("[before] 'var multiplyBy3 = makeMultiplier(3);'");
var multiplyBy3 = makeMultiplier(3);
console.log("[after] 'var multiplyBy3 = makeMultiplier(3);'");
console.log("[before] 'console.log(multiplyBy3(10));'");
console.log(multiplyBy3(10));
console.log("[after] 'console.log(multiplyBy3(10));'");
Additionally, I'll show an alternate example where we multiply by 4:
function makeMultiplier(multiplier) {
console.log("[enter] makeMultiplier");
var myFunc = function(x) {
console.log("[enter] myFunc");
return multiplier * x;
}
return myFunc;
}
console.log("[before] 'var multiplyBy4 = makeMultiplier(4);'");
var multiplyBy4 = makeMultiplier(4);
console.log("[after] 'var multiplyBy4 = makeMultiplier(4);'");
console.log("[before] 'console.log(multiplyBy4(10));'");
console.log(multiplyBy4(10));
console.log("[after] 'console.log(multiplyBy4(10));'");

Execution order of simple function

I am a bit new to javascript, i was just trying the below snippet:
_getUniqueID = (function () {
var i = 1;
return function () {
return i++;
};
}());
s = _getUniqueID();
console.log(s); // 1
console.log(_getUniqueID()); // 2
I was under the impression that i would have to do s() to get 1 as the result and i was thinking that _getUniqueID() returns a function rather than execute the funtion inside it. Can somebody explain the exact execution of this function please ?
What you're seeing here is a combination of Javascript's notion of closure combined with the pattern of an immediately invoked function expression.
I'll try to illustrate what's happening as briefly as possible:
_getUniqueID = (function () {
var i = 1;
return function () {
return i++;
};
}()); <-- The () after the closing } invokes this function immediately.
_getUniqueID is assigned the return value of this immediately invoked function expression. What gets returned from the IIFE is a function with a closure that includes that variable i. i becomes something like a private field owned by the function that returns i++ whenever it's invoked.
s = _getUniqueID();
Here the returned function (the one with the body return i++;) gets invoked and s is assigned the return value of 1.
Hope that helps. If you're new to Javascript, you should read the book "Javascript, the Good Parts". It will explain all of this in more detail.
_getUniqueID = (function () {
var i = 1;
return function () {
return i++;
};
}());
s = _getUniqueID();
console.log(s); // 1
console.log(_getUniqueID()); // 1
when you do () it calls the function,
a- makes function recognize i as global for this function.
b- assigns function to _getUniqueID
you do s = _getUniqueID();,
a - it assigns s with return value of function in _getUniqueID that is 1 and makes i as 2
when you do _getUniqueID() again it will call the return function again
a- return 2 as the value and
b makes value of i as 3.
This is a pattern used in Javascript to encapsulate variables. The following functions equivalently:
var i = 1;
function increment() {
return i ++;
}
function getUniqueId() {
return increment();
}
But to avoid polluting the global scope with 3 names (i, increment and getUniqueId), you need to understand the following steps to refactor the above. What happens first is that the increment() function is declared locally, so it can make use of the local scope of the getUniqueId() function:
function getUniqueId() {
var i = 0;
var increment = function() {
return i ++;
};
return increment();
}
Now the increment function can be anonymized:
function getUniqueId() {
var i = 0;
return function() {
return i ++;
}();
}
Now the outer function declaration is rewritten as a local variable declaration, which, again, avoids polluting the global scope:
var getUniqueId = function() {
var i = 0;
return (function() {
return i ++;
})();
}
You need the parentheses to have the function declaration act as an inline expression the call operator (() can operate on.
As the execution order of the inner and the outer function now no longer make a difference (i.e. getting the inner generator function and calling it, or generate the number and returning that) you can rewrite the above as
var getUniqueId = (function() {
var i = 0;
return function() {
return i ++;
};
})();
The pattern is more or less modeled after Crockford's private pattern
_getUniqueID = (function () {
var i = 1;
return function () {
return i++;
};
}());
console.log(_getUniqueID()); // 1 , this surprised me initially , I was expecting a function definition to be printed or rather _getUniqueID()() to be called in this fashion for 1 to be printed
So the above snippet of code was really confusing me because I was't understanding that the above script works in the following manner, by the time the IFFE executes _getUniqueID is essentially just the following:
_getUniqueID = function () {
i = 1
return i++;
};
and hence,
_getUniqueID() // prints 1.
prints 1.
Note: please note that I understand how closures and IFFE's work.

At which point is the argument passed in this closure?

Taken from Secrets of the JavaScript Ninja, Listing 5.14 passes the num argument of isPrime to a memoized function, I assumed the num argument would be visible in #1, and not in #2, But it's actually The other way around!
Function.prototype.memoized = function(key){
this._values = this._values || {};
return this._values[key] !== undefined ?
this._values[key] :
this._values[key] = this.apply(this, arguments);
};
Function.prototype.memoize = function() {
var fn = this; //#1
console.log(Array.prototype.slice.call(arguments)); // Prints []
return function(){ //#2
console.log(Array.prototype.slice.call(arguments)); //Prints [17]
return fn.memoized.apply(fn, arguments);
};
};
var isPrime = (function(num) {
var prime = num != 1;
for (var i = 2; i < num; i++) {
if (num % i == 0) {
prime = false;
break;
}
}
return prime;
}).memoize();
assert(isPrime(17), "17 is prime"); //#3
How is it possible that the num argument (17 in this case) is visible only in the inner closure (#2) and not in the wrapping memoize function? I don't understand at which point the memoize() call passes the num argument to the closure in #2.
PS. To reiterate, and complement the Question above: Why can't I see the num argument in #1?
Thank you.
Because #2 is the function that is assigned to isPrime. And you pass 17 to isPrime. On the other hand, you call .memoize (#1) without passing any arguments to it:
(function() { ... }).memoize()
// ^^ no arguments
I don't understand at which point the memoize() call passes the num argument to the closure in #2.
It doesn't. memoize returns a new function and it's that function to which the argument is passed.
Because at that point, the anonymous function has't been called.
What you are doing is calling memoize, with your anonymous function as the this value and no arguments (hence the empty arguments array)
memoize then returns a function, which basically checks "has this function already been called with this argument", and either return the previous value if so, or calls the function and stores its return value if not.
What this means is that your function is only called when you actually do isPrime(17), and at that point your are inside the function where it says return function() {...} and that's where you can see your argument.

Javascript closure and IIFE (immediately invoked function expressions)

Closures store their outer variables by reference (and not by value). In the below code, however, I want to store by value. Can anyone show me how to do it using IIFE?
var i = -1;
var f = function () {
return i; // I want to capture i = -1 here!
};
i = 1;
f(); // => 1, but I want -1
What you've posted is in fact not an IIFE: that stands for immediately invoked function expression; you have a function but you're not immediately invoking it!
That aside, the idea here is to store the interesting bit of state in a function argument, so that it's a distinct reference. You do that by creating another function (the Function Expression part), and then invoking it with the globals whose state you want to capture (the Immediately Invoked part). Here's what it looks like:
var i = -1;
var f = (function(state) { // this will hold a snapshot of i
return function() {
return state; // this returns what was in the snapshot
};
})(i); // here we invoke the outermost function, passing it i (which is -1).
// it returns the inner function, with state as -1
i = 1; // has no impact on the state variable
f(); // now we invoke the inner function, and it looks up state, not i
As IIFE - Immediately invoke the function.
var i = -1;
var f = function () {
return i; // I want to capture i = -1 here!
}();// invoked here
i = 1;
console.log(f);

how to use function(1)(2) in javascript? and how does it work?

I understand calling function(1) but not function(1)(2), how does it work?
also possible for function(1)(2)(3)(4) too?
In this case you are supposing that function(1) returns a function, than you are calling this new, anonymous function with an argument of 2.
See this example:
function sum(a) {
return function(b) {
return a+b;
}
}
// Usage:
window.alert(sum(5)(3)); // shows 8
var add2 = sum(2);
window.alert(add2(5)); // shows 7
window.alert(typeof(add2)); // shows 'function'
Here we create a function sum that takes one argument. Inside the function sum, we create an anonymous function that takes another argument. This anonymous function is returned as the result of executing sum.
Note that this anonymous function is a great example of what we call closure. A closure is a function that keeps the context in which it was created. In this case, it will keep the value of the variable a inside it, as did the example function add2. If we create many closures, they are independent as you can see:
var add3 = sum(3);
var add4 = sum(4);
window.alert(add3(3)); // shows 6
window.alert(add4(3)); // shows 7
Furthermore, they won't get "confused" if you have similarly named local variables:
var a = "Hello, world";
function multiply(a) {
return function(b) {
return a * b;
}
}
window.alert(multiply(6)(7)); // shows 42
var twoTimes = multiply(2);
window.alert(typeof(twoTimes));
window.alert(twoTimes(5));
So, after a call to sum(2) or multiply(2) the result is not a number, nor a string, but is a function. This is a characteristic of functional languages -- languages in which functions can be passed as parameters and returned as results of other functions.
You have a function that returns a function:
function f(n) {
return function(x) {
return n + x;
};
}
When you call f(1) you get a reference to a function back. You can either store the reference in a variable and call it:
var fx = f(1);
var result = fx(2);
Or you can call it directly:
var result = f(1)(2);
To get a function that returns a function that returns a function that returns a function, you just have to repeat the process:
function f(n) {
return function(x) {
return function(y) {
return function(z) {
return n + x + y + z;
}
}
};
}
If your function returns a function, you can call that too.
x = f(1)(2)
is equivalent to:
f2 = f(1)
x = f2(2)
The parenthesis indicate invocation of a function (you "call" it). If you have
<anything>()
It means that the value of anything is a callable value. Imagine the following function:
function add(n1) {
return function add_second(n2) {
return n1+n2
}
}
You can then invoke it as add(1)(2) which would equal 3. You can naturally extend this as much as you want.

Categories