What's this ?
Here I will try to answer the questions posted by Dmitry Baranovskiy in his blog post. It basically include intermediated to some extends of advance JavaScript concepts. All the questions are pretty simple but will help you to understand about core concepts JavaScript.
The features in JS like Objects, Arrays, Closures, Prototype etc are covered in this session. Each question can be approach in different ways , so I try to give different approaches to some questions. If you can find any better solution please contribute to this.
Questions
1. Find the biggest element in the array of numbers. Use function Math.max
for this
Ok.. So the first approach coming in the mind is just loop through the array and find the greater one.
var numberArray = [1, 2, 3, 4, 10, 5, 6, 7]; //i just want the output var i, len = numberArray.length, imGreater = numberArray[0];//let set the greater as the first element for (i = 0; i < len; i++) { if (imGreater < numberArray[i]) { imGreater = numberArray[i]; } } console.log(imGreater);//10
But in the question it is mentioned that we need to use Math.max. It will return the number with the highest value.
//But ..I want to use Math.max for (i = 0; i < len; i++) { imGreater = Math.max(imGreater, numberArray[i]); } console.log(imGreater);//10
Fine , will try to get rid of the for loop , we can use "forEach" property of array but internally it do something similar but it don’t have older IE support
numberArray.forEach(function (num) { imGreater = Math.max(imGreater, num); }); console.log(imGreater);//10
Ok. Let see the Math.max function, it can accept only numbers if we pass the array directly it will give NaN , so how can we convert the array into numbers as argument. Since it’s a function it has apply and the way to do that is well explained in MDN
imGreater = Math.max.apply(null, numberArray); console.log(imGreater);//10
So this is the answer . ? I just showed all the ways, if any JS programmer did this at different stages of their learning curve.
2. Transform array of numbers to array of functions that will alert that digits
This question seems to be bit hard? Ok. Now what we want is an array of functions. Anything we can store in array, functions , objects, strings , number even array. So after converting it should look like this
[function (){...}, function (){...}, function (){...}, function (){...}]
In this case we can iterate through the array and convert each element to a function and we can call the function like "numberArray[1](); numberArray[2]();"
var numberArray = [1, 2, 3, 4, 10, 5, 6, 7]; for (i = 0; i < len; i++) { var num = numberArray[i]; numberArray[i] = function () { console.log(num); }; } numberArray[1]();//7 numberArray[4]();//7
So here you can see all the functions are returning ‘7’ the last element of the array. Why .??
The problem is ‘num’ variable value is 7 after the execution of for loop , and this value is returned by all the function . So in this approach I will use closure, you can find a lot of explanationabout closure using inside for loop.
for (i = 0; i < len; i++) { (function (num) { numberArray[i] = function () { console.log(num); }; }(numberArray[i])); } numberArray[1]();//2 numberArray[4]();//10
Confused with closure, don’t worry you can keep on readingabout it :) . It’s the most powerful tool of JS, when you got the idea about it you can just start juggling with your code.
Ok, so the same thing we can achive with native map method of an array.
var numberArray = [1, 2, 3, 4, 10, 5, 6, 7]; numberArray = numberArray.map(function (val) { return function () { console.log(val); }; }); numberArray[1](); //2 numberArray[4](); //10
3. Sort array of objects by number of object properties
We can store Object also in an array. So we want to sort an array based on the number of properties of that object. So to find the number of properties of an object there are few methods. Objects properties can also be iterated with for(var i in object) . JavaScript objects acts like associative arrays.
var obj = {a : 'a', b : 'b', c : 'c'}; var count = 0; for (var i in obj){ if(obj.hasOwnProperty(i)) count++; } console.log(count);//3
But we have Object.keys in modern browsers. So we can use that property and for sorting an array will use normal Array.sort
var objectArray = [{a : 'a', b : 'b'}, {a : 'a'}, {a : 'a', b : 'b', c : 'c'}]; objectArray.sort(function (a, b) { return Object.keys(a).length - Object.keys(b).length; }); console.log(objectArray); // [{a : 'a'}, {a : 'a', b : 'b'}, {a : 'a', b : 'b', c : 'c'}]
4. 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.
For this question, answer is posted in Baranovskiy’s post itself and its almost 5 years back.Ok.. I am trying this a bit late :). But when I execute the function in strict mode (its 2013 rt), it gives an error, because arguments.callee cannot be accessed in strict mode.
So I will try an another approach , and in the question its mentioned that we cannot use any global variable , I will go for a try with closure , Immediately-Invoked Function Expression (IIFE).
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
5. Make this syntax possible: var a = (5).plus(3).minus(6); //2
This seems like an impossible syntax. But when I think about prototype and Number object everything is possible. JavaScript objects have an attribute, a pointer to another object. This pointer is called as prototype.
Here I will add plus and minus function to Number object's prototype , so it will be available for all numbers
Number.prototype.plus = function (n) { return this + n; }; Number.prototype.minus = function (n) { return this - n; }; var a = (5).plus(3).minus(6); console.log(a);//2
I didnt find any other way :)
6. Make this syntax possible: var a = add(2)(3); //5
This is my favorite question, and i like to play with closure.
var add = function (a) { return function (b) { return a + b; }; }; console.log(add(2)(3));//5
Is it possible to do add(1)(2)(3)(4)... :) ?