secret-of-the-javascript-ninja-exercise-answers

This article is used to record the exercise answers of the book Secrets of the Javascript Ninja-Manning

Chapter 2

  1. 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.

  2. 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.

  3. 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.

  4. 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

  1. The following function calculates the sum of the passed-in arguments by using the arguments object:

    1
    2
    3
    4
    5
    6
    7
    function 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
    9
    function 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 array

  2. After running the following code, what are the values of variables ninja and samurai?

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    function getSamurai(samurai){ 
    "use strict"
    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 through arguments arguments. But in the second method, we can change it throught arguments

  3. When running the following code, which of the assertions will pass?

    1
    2
    3
    4
    5
    6
    function 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’.

  4. When running the following code, which of the assertions will pass?

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    var 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 as whoAmI() called as a method of ninja1.

    assert(ninja2.whoAmI() === ninja1, " ninja1 again?"); will fail as whoAmI() called as a method of ninja2 not ninja1.

    assert(identify() === ninja1, "ninja1 again?"); will fails as identify() 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.

  5. When running the following code, which of the assertions will pass?

    1
    2
    3
    4
    5
    6
    7
    8
    9
    function 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 as whoAmI 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 ninja1

    assert(ninja2.whoAmI() === ninja2, "ninja2 here?"); will fails, as methoned abboe, in nanja1’s whoAmI method, this will always point to ninja1.

  6. Which of the following assertions will pass?

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    function 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 as whoAmI is a function bound to ninja1.

    assert(ninja2.whoAmI() === ninja2, "ninja2 here?"); will fail as whoAmI is a function bound to nanja1.

Chapter 5

  1. Closures allow functions to A: Access external variables that are in scope when the function is defined

  2. Closures come with memory costs (closures keep alive the variables that are in scope when the function is defined)

  3. 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
    25
    function 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();
  4. 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
    14
    function 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

  5. 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.

  6. 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.

  7. Where and why will the following code throw an exception?

    1
    2
    3
    4
    5
    6
    7
    8
    9
    getNinja(); getSamurai();

    //throws an exception

    function getNinja() {

    return "Yoshi"; }

    var getSamurai = () => "Hattori";

    An exception will be thrown when trying to invoke the getSamurai() function. The getNinja function is defined with a funcion declaration and will be created before any of the code is executed. The getSamurai 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.