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
addEventListener
method 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;
addEventListener
allows 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
arguments
is not an array, however,numbers
in the second function is an arrayAfter running the following code, what are the values of variables
ninja
andsamurai
?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");samurai
will be “Toyotomi”,ninja
will be “Fuma”;In the
getSamurai
method, “use strict” is used. So we can not change the value of samurai througharguments
arguments. But in the second method, we can change it throughtarguments
When 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,this
will be ‘undefined’.assert(whoAmI2() === window, "Window?");
will pass as under the nonstrict mode, when we invoke a function as a function,this
will 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,this
will be the global variable “window”assert(ninja1.whoAmI.call(ninja2) === ninja2, "ninja2 here?");
will pass as using call to supply the function context,this
refers 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 aswhoAmI
is 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,this
will 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 aswhoAmI
is a function bound to ninja1.assert(ninja2.whoAmI() === ninja2, "ninja2 here?");
will fail aswhoAmI
is 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?
const
can’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?
var
is 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. ThegetNinja
function is defined with a funcion declaration and will be created before any of the code is executed. ThegetSamurai
function, 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.