Read Time:5 Minute, 35 Second
- Found this test from the internet (Download: JavaScript_Skill_Test-blank)
- Tried to solve without using Google. FAILED.
- With help from Google, solved questions. There was someone’s solution for exact same questions; I resisted a lot to not see his solution. Some questions are referred to understand what question was.
- If I get this test in the interview without using internet, I probably failed completely. Need more study…
- Solution: JavaScript_Skill_Test-solution
Javascript Skill Test
Q1. Fix the below JavaScript code so that the correct index is printed to console.log on each iteration.
(function() { var index length = 10; for (index = 0; index < this.length; index++) { setTimeout(function() { console.log(index); }, 100); } }());
Solution: [HTML] The loop finishes before the first timeout;thus, it shows 10 for 10 times. Solution is pass actual value of the loop to the setTimeout function. http://stackoverflow.com/a/5226349
(function() { var index length = 10; for (index = 0; index < this.length; index++) { (function(index){ setTimeout(function() { console.log(index); }, 100); })(index); } }());
Q2. Modify the below JavaScript so that it is called just after the DOM has loaded. No legacy browser support required.
(function() { document.getElementById("test").innerHTML = "Hello World"; }());
Solution: [HTML]
window.onload = function() { document.getElementById("test").innerHTML = "Hello World"; };
Q3. Modify the below code so that it will only display a message if the user is using Internet Explorer 7
(function() { alert("Hello World"); } )();
Solution: [HTML]
<!--[if IE 7]> <script type="text/javascript"> (function() { alert("Hello World"); } )(); </script> <![endif]--><span style="line-height: 1.714285714; color: #444444; font-family: 'Open Sans', Helvetica, Arial, sans-serif; font-size: 1rem;"> </span>
Q4. Finish the below JavaScript by implementing a simple flow control function (flow) that can take the provided array of functions and process them asynchronously before making a final callback.
(function() { var array = [ function(callback) { console.log("first function called in " + (new Date().getTime() - timestamp) + "ms"); callback(); }, function(callback) { console.log("second function called in " + (new Date().getTime() - timestamp) + "ms"); callback(); }, function(callback) { console.log("third function called in " + (new Date().getTime() - timestamp) + "ms"); callback(); } ], timestamp = new Date().getTime(); function flow(array, callback) { } flow(array, function() { console.log("all functions finished in " + (new Date().getTime() - timestamp) + "ms"); }); }());
Solution: [HTML]
(function() { var array = [ function(callback) { console.log("first function called in " + (new Date().getTime() - timestamp) + "ms"); callback(); }, function(callback) { console.log("second function called in " + (new Date().getTime() - timestamp) + "ms"); callback(); }, function(callback) { console.log("third function called in " + (new Date().getTime() - timestamp) + "ms"); callback(); } ], timestamp = new Date().getTime(); var i = 0; function acallback(array_elm, index, callback) { array_elm(function(){ if(++i == array.length) { callback(); return; } acallback(array[i], i, callback); }); } function flow(array, callback) { acallback(array[0], i, callback); } flow(array, function() { console.log("all functions finished in " + (new Date().getTime() - timestamp) + "ms"); }); }());
Q5. Modify the below code so that the return value can also be returned with a callback function (if a callback function has been specified).
(function() { function isArray(array) { return typeof(array) === "object" && (array instanceof Array); } var result = isArray([ "item1", "item2", "item3" ]); console.log("isArray: " + result); }());
Solution: [HTML]
(function() { function isArray(array, callback) { var bArray = typeof(array) === "object" && (array instanceof Array); if(typeof callback !== 'undefined') { callback(bArray); } else { return bArray; } } var testArray = [ "item1", "item2", "item3" ]; var result = isArray(testArray, function(result){ console.log("isArray with Callback = " + result); }); console.log("isArray with No callback = " + isArray(testArray)); }());
Q6. Modify the below JavaScript code so that it uses a closure to return the response.
(function() { function hello(name, age) { return name + ", who is " + age + " years old, says hi!"); } console.log(hello('John', 33)); })();
Solution: [HTML]
(function() { function hello(name, age) { return (name + ", who is " + age + " years old, says hi!"); } console.log(hello('John', 33)); })();
Q7. Optimize the below JavaScript to minimize the number of redraws and reflows required.
(function() { var element, index, length, content = document.getElementById("content"), data = [{ id: 1, name: "John", color: "green" }, { id: 2, name: "Sally", color: "pink" }, { id: 3, name: "Andrew", color: "blue" }, { id: 4, name: "Katie", color: "purple" }], for (index = 0, length = data.length; index++) { element = document.createElement("li"); content.appendChild(element); element.setAttribute("id", data[index].id); element.innerHTML = "<strong>" + data[index].name + "</strong>"; element.style.color = data[index].color; } })();
Solution: [HTML]
(function() { var element, index, length, content = document.getElementById("content"), data = [{ id: 1, name: "John", color: "green" }, { id: 2, name: "Sally", color: "pink" }, { id: 3, name: "Andrew", color: "blue" }, { id: 4, name: "Katie", color: "purple" }]; var html = ""; for (index = 0; index < data.length; index++) { html += "<li id='"+data[index].id+"' style='color:"+data[index].color+";'><strong>"+data[index].name+"</strong></li>"; } content.innerHTML = html; })();
Q8. Using the below JavaScript code as a starting point, implement a chain-able DOM Wrapper API that operates in a similar fashion to jQuery’s API (No native prototype extensions).
(function() { NodeList.prototype.show = function() { var array = Array.prototype.slice.call(this, 0); array.forEach(function(node) { node.style.display = "block"; }); } NodeList.prototype.hide = function() { var array = Array.prototype.slice.call(this, 0); array.forEach(function(node) { node.style.display = "none"; }); } document.querySelectorAll("#test").show(); document.querySelectorAll("#test").hide(); }());
Solution: [HTML]
(function() { // Extend native javascript objects NodeList.prototype.show = function() { var array = Array.prototype.slice.call(this, 0); array.forEach(function(node) { node.style.display = "block"; }); return this; }; NodeList.prototype.hide = function() { var array = Array.prototype.slice.call(this, 0); array.forEach(function(node) { node.style.display = "none"; }); return this; }; document.querySelectorAll("#test").show().hide(); // document.querySelectorAll("#test").show(); // document.querySelectorAll("#test").hide(); }());
Q9. The below JavaScript is used to handle mousemove events amongst 3 divs which are nested inside each other. Find and fix the problem which is causing too many events to get fired.
<div id="box1"> Box 1 <div id="box2"> Box2 <div id="box3">Box3</div> </div> </div> <script> (function() { var boxes = [ document.getElementById("box1"), document.getElementById("box2"), document.getElementById("box3") ]; console.log(boxes); boxes[0].addEventListener("mousemove", function(event) { console.log("Box 1"); }); boxes[1].addEventListener("mousemove", function(event) { console.log("Box 2"); }); boxes[2].addEventListener("mousemove", function(event) { console.log("Box 3"); }); })(); </script>
Solution: [HTML]
(function() { var boxes = [ document.getElementById("box1"), document.getElementById("box2"), document.getElementById("box3") ]; boxes[0].addEventListener("mousemove", function(event) { console.log("Box 1"); // fix that call ancestor elements' event event.stopPropagation(); }); boxes[1].addEventListener("mousemove", function(event) { console.log("Box 2"); // fix that call ancestor elements' event event.stopPropagation(); }); boxes[2].addEventListener("mousemove", function(event) { console.log("Box 3"); // fix that call ancestor elements' event event.stopPropagation(); }); })();