This article is used to record the exercise answers of the book Secrets of the Javascript Ninja-Manning
Chapter 2
What are the twp phases in lifecycle of a client-side web application?
The two phases in the lifecycle of a client-side web application are page building and even handling.
In the page building phase, the user interface of our page is built by processing the HTML code, which is a blueprint of the DOM (Document Object Model) and by exectuing main line JavaScript code. In this phase, the processing of HTML code will be paused when the browser meet the
<script>tag, instead the browser will try to run the Javascript code.After the last HTML node is processed, the page enters the event-handling phase, in which various events are processed through event loop.
What is the main advantage of using the
addEventListenermethod to register an event handler versus assigning a handler to a specific element property?When assigning event handler to a specific element property, we can only register one event handler;
addEventListenerallows us to register as many event handlers as we necessary.How many events can be processed at once?
Javascript is based on a single-threaded execution model, in which events are processed one at a time.
In what order are events from the event queue processed
Events are processed in the order in which they were generated: first in , first out. Just like the queue.
Chapter 4
The following function calculates the sum of the passed-in arguments by using the arguments object:
1
2
3
4
5
6
7function sum(){
var sum = 0;
for(var i = 0; i < arguments.length; i++){
sum += arguments[i];
}
return sum;
}By using the rest parameters, rewrite the sum function so that it doesn’t use the arguments object.
1
2
3
4
5
6
7
8
9function sum(...numbers)
{
var sum = 0;
for(var i = 0; i < numbers.length; i++)
{
sum += numbers[i];
}
return sum;
}This is the simplest way to rewrite the code. Actualy, there are a lot of other ways to rewrite it. The point is that
argumentsis not an array, however,numbersin the second function is an arrayAfter running the following code, what are the values of variables
ninjaandsamurai?1
2
3
4
5
6
7
8
9
10
11
12
13function getSamurai(samurai){
arguments[0] = "Ishida";
return samurai;
}
function getNinja(ninja){
arguments[0] = "Fuma";
return ninja;
}
var samurai = getSamurai("Toyotomi");
var ninja = getNinja("Yoshi");samuraiwill be “Toyotomi”,ninjawill be “Fuma”;In the
getSamuraimethod, “use strict” is used. So we can not change the value of samurai throughargumentsarguments. But in the second method, we can change it throughtargumentsWhen running the following code, which of the assertions will pass?
1
2
3
4
5
6function whoAmI1(){ "use strict"; return this; }
function whoAmI2(){ return this; }
assert(whoAmI1() === window, "Window?");
assert(whoAmI2() === window, "Window?");assert(whoAmI1() === window, "Window?");will fail as under the strict mode, when we invoke a function as a function,thiswill be ‘undefined’.assert(whoAmI2() === window, "Window?");will pass as under the nonstrict mode, when we invoke a function as a function,thiswill usually be the global variable ‘window’.When running the following code, which of the assertions will pass?
1
2
3
4
5
6
7
8
9
10
11
12
13
14var ninja1 = {
whoAmI: function(){
return this;
}
};
var ninja2 = {
whoAmI: ninja1.whoAmI
};
var identify = ninja2.whoAmI;
assert(ninja1.whoAmI() === ninja1, "ninja1?"); assert(ninja2.whoAmI() === ninja1, " ninja1 again?");
assert(identify() === ninja1, "ninja1 again?");
assert(ninja1.whoAmI.call(ninja2) === ninja2, "ninja2 here?");assert(ninja1.whoAmI() === ninja1, "ninja1?");will pass aswhoAmI()called as a method of ninja1.assert(ninja2.whoAmI() === ninja1, " ninja1 again?");will fail aswhoAmI()called as a method of ninja2 not ninja1.assert(identify() === ninja1, "ninja1 again?");will fails asidentify()is called as a function,thiswill be the global variable “window”assert(ninja1.whoAmI.call(ninja2) === ninja2, "ninja2 here?");will pass as using call to supply the function context,thisrefers to ninja2.When running the following code, which of the assertions will pass?
1
2
3
4
5
6
7
8
9function Ninja(){
this.whoAmI = () => this;
}
var ninja1 = new Ninja();
var ninja2 = {
whoAmI: ninja1.whoAmI
};
assert(ninja1.whoAmI() === ninja1, "ninja1 here?");
assert(ninja2.whoAmI() === ninja2, "ninja2 here?");assert(ninja1.whoAmI() === ninja1, "ninja1 here?");will pass aswhoAmIis an arrow function inherits the function context from the context in which it was created. Because it was created during the construction of ninja1, this will always point ninja1assert(ninja2.whoAmI() === ninja2, "ninja2 here?");will fails, as methoned abboe, in nanja1’s whoAmI method,thiswill always point to ninja1.Which of the following assertions will pass?
1
2
3
4
5
6
7
8
9
10
11
12function Ninja(){
this.whoAmI = function(){
return this;
}.bind(this);
}
var ninja1 = new Ninja();
var ninja2 = {
whoAmI: ninja1.whoAmI
};
assert(ninja1.whoAmI() === ninja1, "ninja1 here?");
assert(ninja2.whoAmI() === ninja2, "ninja2 here?");assert(ninja1.whoAmI() === ninja1, "ninja1 here?");will pass aswhoAmIis a function bound to ninja1.assert(ninja2.whoAmI() === ninja2, "ninja2 here?");will fail aswhoAmIis a function bound to nanja1.
Chapter 5
Closures allow functions to A: Access external variables that are in scope when the function is defined
Closures come with memory costs (closures keep alive the variables that are in scope when the function is defined)
In the following code example, mark the identifiers accessed through closures:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25function Samurai(name) {
var weapon = "katana";
this.getWeapon = function(){
//accesses the local variable: weapon
return weapon;
};
this.getName = function(){
//accesses the function parameter: name
return name;
};
this.message = name + " wielding a " + weapon;
this.getMessage = function(){
//this.message is not accessed through a closure
//it is an object property (and not a variable)
return this.message;
};
}
var samurai = new Samurai("Hattori");
samurai.getWeapon();
samurai.getName();
samurai.getMessage();In the following code, how many execution contexts are created, and what’s the largest size of the execution context stack?
1
2
3
4
5
6
7
8
9
10
11
12
13
14function perfom(ninja) {
sneak(ninja);
infiltrate(ninja);
}
function sneak(ninja) {
return ninja + " skulking";
}
function infiltrate(ninja) {
return ninja + " infiltrating";
}
perfom("Kuma");The largesst size of the execution context stack is 3.
global->perform->sneak
global->perform
global->perform->infiltrate
Which keyword in JavaScript allows us to define variables that can’t be reas- signed to a completely new value?
constcan’t be reassigned to a completely new value, but wa can change the variables’s attributes. For example, we can change the const array to any dimensions.What’s the difference between var and let?
varis used to define functional or global scoped variable, let is used to define block, function, and global soped variable.Where and why will the following code throw an exception?
1
2
3
4
5
6
7
8
9getNinja(); getSamurai();
//throws an exception
function getNinja() {
return "Yoshi"; }
var getSamurai = () => "Hattori";An exception will be thrown when trying to invoke the
getSamurai()function. ThegetNinjafunction is defined with a funcion declaration and will be created before any of the code is executed. ThegetSamuraifunction, on the other hand, is an arrow funcition that’s created when teh execution reaches it, so it will be undefined when we try to invoke it.