I am to write up some code using Javascript. Here is what we are to do:
"Implement a javascript Fibonacci numbers using closures. Specifically, write an function that stores two consecuitive Fibonacci numbers, initially 0 and 1. The function also defines and returns a nested function getNext(). The getNext() function updates the two stored Fibonacci numbers to the next two Fibonacci numbers and returns the current one. E.g. on the first call to getNext() the return value is 0, on the next call it is 1, then 1 again, then 2, etc."
I kind of understand this but not really. Could someone maybe help clarify? Thanks!
The basic idea behind closures is that, since closers bind all local data by value, you can use them to initialize and then modify variables that are only local to that "instance" of the generated function.
Since this seems like homework, I'm going to answer a different question using closures: Use closures to get perfect squares (1, 4, 9, etc.), one at a time.
function makeSquareIteratorFunction() {
var squareRoot = 1;
var getNext = function() {
// Calculate the number you need to return
var square = squareRoot * squareRoot;
// Apply side effects. In this case just incrementing the counter, but with
// Fibonacci you will need to be a little more creative :-)
// You might also prefer to do this first. Depends on your approach.
squareRoot = squareRoot + 1;
// Return the value
return square;
};
// Return the function object, which can then be called later
return getNext;
}
// Usage
var getNextSquare = makeSquareIteratorFunction();
alert(getNextSquare()); // 1
alert(getNextSquare()); // 4
alert(getNextSquare()); // 9
Now, it's worth pointing out that the local variables defined in the outer function (makeSquareIteratorFunction) are localized and bound to the closure. So if you call makeSquareIteratorFunction() multiple times, the later ones will be independent of the first one:
var getNextSquare1 = makeSquareIteratorFunction();
alert(getNextSquare1()); // 1
alert(getNextSquare1()); // 4
var getNextSquare2 = makeSquareIteratorFunction();
alert(getNextSquare2()); // 1 (!) because it's a new closure, initialized the same way
alert(getNextSquare1()); // 9 (!) because it was "on" 4 last time
Hopefully that helps explain it a little? If not, leave a comment. :-)
I just wanted to post a little bit more up to date answer - the fibonacci closure is more readable written using modern JavaScript
function fibonacci() {
let x = 0;
let y = 1;
let z = 0;
return function getNext() {
[z, x, y] = [x, y, x + y];
return z;
};
}
let fun = fibonacci();
for (let i = 0; i < 10; i++) {
console.log(fun());
}
var fibonacci = (function () {
var arr = [0, 1];
return function () {
var num = arr[arr.length - 1],
len = arr.length;
arr.push(arr[len - 1] + arr[len - 2]);
return num;
};
}());
//test
var i;
for (i = 0; i < 10; i++) {
console.log(fibonacci());
}
//1,1,2,3,5,8,13,21,34,55
See the description in http://sarathsaleem.github.com/JavaScriptTasks/
I did this as an answer to this question
Write a function which will return you first two times 1, then 2, then 3, then 5 and so on (Fibonacci numbers). Don’t use any global variables.
fibonacci = ([f0, f1] = [0, 1]) => () => ([f0, f1] = [f1, f0 + f1])[0];
I just wanted to give a more up to date answer written using modern JavaScript.
Related
Example 1.
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;
}();
Example 2.
var memoizer = function (memo, fundamental) {
var shell = function (n) {
var result = memo[n];
if (typeof result !== 'number') {
result = fundamental(shell, n);
memo[n] = result;
}
return result;
};
return shell;
};
var fibonacci = memoizer([0, 1], function (shell, n) {
return shell(n - 1) + shell(n - 2);
});
Above are 2 code snippets from Crockford's book to demonstrate the concept of memoization.
Question 1. How do I invoke function fibonacci from any of 2 examples? By usual way fibonacci (5)?
Question 2. As I can see, argument "n" is not defined anywhere when calling var fib = function (n) { or var shell = function (n) {.
In the first example of fibonacci function I'd expect "n" to be defined right after the 2nd line var memo = [0, 1];, and I'd expect "n" to be defined as follows: n = arguments[0];.
However since this doesn't seem to be the case, so I have to ask: how is "n" determined when fibonacci is invoked?
Thanks.
Page from Crockford's books
Question 1: How do I call each one?
The first example, note the }() at the end. This is invoking the function, which in turn gives the fib function back. So fibonacci() in the first example is really fib() with it's own internal references (e.g. memo and fib), memo only being accessible by fib but lasting as a reference as long as a reference to fib exists (the variable holding fibonacci's return).
The second example is similar, except it's substituting a memoizer that accepts an array of items and returns shell, which has access to the array it was passed.
Question 2: What is n as an argument doing?
Since you're really calling a reference to an internally created but externally available fib() and shell() when you call either fibonacci function, you're passing in a new number, which then has it's fibonacci sequence "memoized" by storing it in the internally available memo given at the beginning.
The point is that memoization is like a hash store where computations already known (since they were previously performed and "memoized") are accessible (preventing re-computation), and using Javascript's closure construct allows you to use internally-scoped variables to manage that access.
I have the following problem below:
My For Each
Write a function myForEach that accepts an array and a callback function. The behavior of myForEach should mirror the functionality of the native .forEach() array method as closely as possible.
Below is the code:
let sum = 0;
function addToSum(num) {
sum += num;
}
let nums = [10, 20, 30];
function myForEach(anArray, callback){
for (let i=0; i<anArray.length; i++){
let num = anArray[i];
//console.log(num)
// I don't understand what this line of code is doing...
callback(num, i, anArray);
}
return undefined
}
myForEach(nums, addToSum);
console.log(sum); // 6
The above code works in this higher order function problem but I don't understand why. Specifically, what is the following line of code mean:
callback(num, i, anArray);
why are there 3 arguments? and where are these arguments getting passed to?
"as closely as possible" is quite a harsh requirement. Javascript built-in functions are very complicated! These are the steps that the standard requires you to implement:
http://www.ecma-international.org/ecma-262/7.0/#sec-array.prototype.foreach
In layman's terms, since JS is a highly dynamic language, when you design a built-in function, you cannot just rely on parameters being what you expect them to be. In case of forEach:
the argument can be not an array, and even not an object
it might not have length or its length might be not a number
the callback might be missing or be not a function
and so on. That's why an "as close as possible" implementation should do lots of safety checks before it actually starts looping and calling.
You can find an example of a real-world forEach polyfill on the MDN page (only look if you decided to give up on this):
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach
Read here about it. Javascript doesn't care how many parameters you pass. For example, the following code still works but alerts undefined in the addToSum function:
let sum = 0;
function addToSum(num, i, k, j) {
sum += num;
console.log("i is:" + i);
console.log("k is:" + k);
console.log("j is:" + j);
}
let nums = [10, 20, 30];
function myForEach(anArray, callback) {
for (let i = 0; i < anArray.length; i++) {
let num = anArray[i];
//console.log(num)
// I don't understand what this line of code is doing...
callback(num);
}
return undefined
}
myForEach(nums, addToSum);
console.log(sum);
So the thing that happens in your original code is that i and anArray that you pass does not effect the addToSum function at all, and the only parameter this function need is num so everything works good.
It's a callback function:
callback();
This is the function you passed into myForEach - in your code, it's addToSum, but it's a reference with a different name. It's used in case you have different functions for handling different things. In your code you can just as easily use addToSum and forget about callback altogether:
let sum = 0;
function addToSum(num) {
sum += num;
}
let nums = [10, 20, 30];
function myForEach(anArray) {
for (let i = 0; i < anArray.length; i++) {
let num = anArray[i];
//console.log(num)
// I don't understand what this line of code is doing...
addToSum(num, i, anArray);
}
return undefined
}
myForEach(nums, addToSum);
console.log(sum);
I would like to know how I can sum an algebraic sum.
For example, I have a function with two parameters:
function sumAlga(paramA, paramB) {
return paramA + paramB;
}
How I should do it for algebraic sum in JavaScript?
Incorrect Code
As "don't angry me" has said in the comments, you have return paramA + paramBM not return paramA + paramB so that should fix that (assuming that was an unintentional typo, correct me if we're wrong).
More than two arguments
To accomplish this with any number of parameters you could do the following,
function algebraicSum() {
var sum = 0;
for (var i = 0; i < arguments.length; ++i) {
sum += arguments[i];
}
return sum;
}
Usage
algebraicSum(1,2,3,4) = 10;
algebraicSum(1,-2,3) = 2;
you can try something like this:
var age_child = parseInt(10);
var age_gap = parseInt(10);
alert(age_child+age_gap);
Unlike Java or C, which are strongly typed languages, Javascript is smart and hence is also called a weakly typed language. You don't have to specify the data-type of your variable while declaring it. but in this case, you should specify the data type to match with your operations.
The main purpose is to have a function which could be used as callback for Array#reduce, for example.
An array with values could be summed by taking the function and a start value of zero (this is necessary, if an empty array or an array with only one item is supplied).
function add(a, b) {
return a + b;
}
console.log([1, 2, -5].reduce(add, 0));
console.log([1].reduce(add, 0));
console.log([].reduce(add, 0));
The following code uses an arrow function, which has some differences to the standard function, but is sometimes shorter.
const add = (a, b) => a + b;
console.log([1, 2, -5].reduce(add, 0));
console.log([1].reduce(add, 0));
console.log([].reduce(add, 0));
I'm studying JavaScript from the book JavaScript: The Good Parts, in the memoization section there is an example about using memoize technique to do Fibonacci problem
We create a general function call memoizer, it takes an memo array and the fundamental function, returns a shell function that manages the memo and calls fundamental function
var memoizer = function(memo, fundamental) {
var shell = function(n) {
var result = memo[n];
if (typeof result !== 'number') {
result = fundamental(shell, n);
memo[n] = result;
}
return result;
};
return shell;
};
And then create fibonacci like this:
var fibonacci = memoizer([0, 1], function(shell, n) {
return shell(n-1) + shell(n-2);
});
If I run fibonacci(10), the result will be displayed exactly.
But the thing that makes me confused is the n parameter shell function in memoizer function. I know that it is the value that we want to compute. But where is it come from? How can I call fibonacci(10), for example, can pass the value 10 to n? And what is exactly the var fibonacci? Is it a function or points to a function object as memoizer?
Thanks for any help!
So, to understand this fully, you need to understand things below as fundamental pieces.
Closure How do JavaScript closures work?
Scope What is the scope of variables in JavaScript?
First class object What is meant by 'first class object'?
So, now look at the code.
var memoizer is assigned as a function that returns an another function inside.
var memoizer = function(memo, fundamental) {
var shell = function(n) {
... do some works ...
};
return shell;
};
Can you see it? var shell is returned at the end of the line in memoizer
And whatever the inner logic is in memoizer, the result of it is assigned to var fibonacci
var fibonacci = memoizer([0, 1], function(shell, n) {
return shell(n-1) + shell(n-2);
});
So, it means fibonacci equals the result of memoizer (Since we excuted it), and the result of memoizer equals shell function. If you read those links given to you by me well, you can understand what is going on behind the scenes.
By the way, the code you've given isn't the best way. Because anyway closure makes an activated object alive that isn't necessary.
This code below is an another way of making fibonacci, this isn't the absolute best way, however, I recommend you to compare this code with your code, and figure the differences out.
var result = [];
result[0] = 1;
result[1] = 1;
function fibonacci(n){
var i;
for(i = 2; i < n; i++){
if(!result[i]){
result[i] = result[i-1] + result[i-2];
}
}
return result[i-1];
}
console.log(fibonacci(10));
I have a dice-rolling bot that spits out results via var roll = new Roll('4#2d20+3'). That constructor makes objects with properties parsed out of the string argument, which resembles this:
aRoll = {
text: '4#2d20+3',
times: 4,
dice: 2,
sides: 20,
modifier: 3,
roll: function() {...}
}
The roll() method should use the object's properties to generate an array of results. This is an exercise to learn what's new in JavaScript, so I'm curious how best to accomplish this.
Old, procedural way:
this.roll = function() {
var total = 0;
for (var i=0; i < this.dice; i++) {
total += Math.floor(Math.random() * this.sides) + 1;
}
return total;
}
My attempt at new Array functional iteration:
this.roll = () => Array(this.dice).fill(0).reduce(state => {
result + Math.floor(Math.random() * state.sides) + 1;
}, this);
This sorta works, but Array(x).fill(0).reduce(... is an ugly hack, and passing this in as state seems like a sign I'm doing the wrong thing.
Is there an Array method I should use instead? Or is the for loop still the cleanest way to accomplish this?
One way to repeat a function n times is
Array.from(Array(n), fn)
To make all of this more readable, you could define, for example
let times = (n, fn) => Array.from(Array(n), fn);
let rand = n => Math.floor(Math.random() * n) + 1;
let sum = a => a.reduce((x, y) => x + y);
and then
roll = function() {
return sum(
times(this.dice,
rand.bind(0, this.sides)));
}
I think I figured out how this “should” be done.
The first issue is straightforward: do not use arrow functions as methods:
An arrow function does not create its own this context, so this has its original meaning from the enclosing context.
this is the whole point of object-orientation, so breaking it is a bad idea. Passing this as map()’s second argument was indeed a code smell.
The second issue: instead of abusing reduce()’s initial value parameter with this to fake a context object, use a closure:
function roll(sides) {
return (total) => {
total + Math.floor(Math.random() * sides) + 1;
};
}
someArray.map(roll(this.sides));
When you pass callbacks as arguments, but need to dynamically give them data that callers don’t provide, closures are the classic solution.
As for the third issue, populating an array the size of an object property, in order to call a function that many times…
There is no built-in boilerplate way. :•) #georg kindly provided a clean implementation of a times() function that reminds me of Ruby’s Number.times(), if you’re interested.