Vainolo's Blog

Archive for the ‘tutorial’ tag

JavaScript Tutorial – Part 5: Statements

leave a comment

Previous Tutorial: Object Creation and Prototype Chains

While theoretically we can do anything with functions and basic data structures, programmers (unlike mathematicians) like their code to be readable and understandable by other human beings. So programming languages (and of course, JavaScript) have some build in statements to help us create more readable and easier to understand programs.

We have the usual suspects: if, for, while, switch, and a new one that I’ll save for the end. Let’s have an example of their use, starting with loop statements:

var min = 0, max = 5;

a = min;
while (a < max) {
    console.info(a);
    a++;
}

a = min;
do {
    console.info(a);
    a++;
} while (a < max);

for (var a = min; a < max; a++) {
    console.info(a);
}

The first loop statement is a while loop, whose formal syntax is:

while (condition) 
    statement

A while is a simple form of loop where the condition is checked and then the statement is executed, repeating this until the condition is false. Pretty simple.

The second loop statement is a do...while loop that is the same as the while loop but the statement of the loop is executed at least once and then the condition is checked.

The last loop statement is a for loop, whose formal syntax is:

for (initialization; condition; update)
    statement

The execution starts by performing all the code in the initialization, then the condition is checked and if it is true, the statement is executed. When it finishes, the update is executed. The condition is checked again and the loop continues always executing update at the end) until condition is false. Note that you can execute many statements in initialization and update using a , (comma) operator between them, like this:

for (var a = 2, b = 4; a < b; a += 2, b += 1) {
    console.info("a=" + a + ", b=" + b);
}

Now let’s see our conditional statements: if and switch:

var a = 1;
if(a === 2) {
    console.info("WAT?");
} else {
    console.info("Yea, that's what I expected");
}

switch (a) {
    case 1:
        console.info("Correct");
        break;
    case 2:
        console.info("WAT?");
        break;
    default:
        console.info("Defaults are always good");
}

Let’s first take a look at the if statements, which is formally defined as:

if (condition1)
    statement1
[else
    statement2]

As the name says, if condition1 is true, statement1 is executed. We can optionally add statement2 that is executed if the condition is false. To check more than one condition, we can chain the condition like this:

if (condition1)
    statement1
else if (condition2)
    statement2
[else
    statement3]

The switch statement is a bit more complex, but sometimes creates more readable code when and there are limited possible values to a variable and limited things we want to do depending on these values. The formal syntax is:

switch (expression) {
    case value1:
        [statement(s)1]
        [break;]
    case value2:
        [statement(s)2]
        [break;]
....
    [default:
        [statement(s)n]]
}

This is a bit more complex, so we’ll take it step by step. First we have an expression that is evaluated and has a value (we’ll call it VALUE). Execution starts top to bottom to find the first case value that is equal to VALUE and if one is found, the code below it is executed. If none is found, and there is a default case, the statements below this case are executed. The location of the default statement doesn’t matter, so you can theoretically put it first, but this is not really what you usually want to do.

One typical error when writing switch statements is to forget the break after the statements of each case, because unlike an if, when a case is matched, ALL of the code below this statement is executed! Not just the code until the next case statement, but ALL of the code below it, until the switch ends, or a break is found. This is good if you want to do the same thing for different case values, like this:

switch (food) {
    case "apple":
    case "orange":
    case "banana":
        console.info("My Favorite");
    case "melon":
        console.info("I Love it!");
        break;
    case "pineapple":
        console.info("I adore these!");
        break;
    default:
        console.info("Not sure, but I'll try");
}

But usually lack of a break is not what you really want.

Going back to loops, their execution can be altered using break and continue. The break statement stops the execution of the loop and continues execution from the first statement after it. The continue statement stops the current iteration of the loop and jumps to check condition in a while loop or to execute update in a for loop:

for (var a = 0; a < 10; <span class="hiddenGrammarError" pre="">a++) {
    if</span> (a == 2)
        continue; // number 2 will not be printed
    if (a > 5)
        break; // loop will end at 6, printing until 5
    console.info(a);
}

// poor man's for loop
var a = 0;
while (true) {
    if (a > 5)
        break;
    console.info(a);
    a++;
}

Last but not least, JavaScript adds a new expression that can be used to iterate over all the attributes of an object. This is a very simple type of reflection that is useful many times. Formally, when attr is a variable name and object is a variable that contains an object reference, the statements is as follows:

 
for (var attr in object) 
  statement

And now a simple example of how this works, a short way to print all attributes of an object and their values:

var obj = { a: 1, b: 2 };
for (var attr in obj) {
    console.info(attr+"="+obj[attr]);
}

I thought I would get to talk also about operators here, and about what equal means in JavaScript (same object? same values?) but this tutorial is getting long so I’ll leave it for next time. Happy JavaScripting!

Written by vainolo

May 17th, 2015 at 10:05 pm

JavaScript Tutorial – Part 4: Object Creation and Prototype Chains

leave a comment

Previous Tutorial: Variable Scope and Closures

The term “Object-Oriented programming (OOP)” has been greatly overused, and JavaScript is not one of the exceptions. For someone who comes from many years programming in Java, learning JavaScript made me realize that the correct name for the paradigm used by programming languages like Java, C++, and C# (to name a few) is not Object-Oriented but Class-Oriented programming. Because in these languages what you are really defining are classes of objects and instantiating them. In contrast, JavaScript is a real Object-Oriented language since you are always handling objects. Sadly time made its thing and there is no way to change the name of the paradigms… so the paradigm used by JavaScript (and other less known languages) is called Prototype-based programming.

So why am I saying all this? Because this is a very important concept that helps understand how the language works.

In tutorial 2, we saw two ways to create objects: inline or with the new keyword before a function name. The third way to do this is using the Object.create(). Unlike the two previous ways of creating object, this one really “feels” like we are copying the existing object when creating another object.

Let’s revisit them and investigate some more. First, objects defined inline:

// Inline object creation
var a = {
    field: "a"
}
console.info("a's constructor: "+a.constructor); // prints "function Object()..."
console.info("a instanceof Object?: " + (a instanceof Object)); // prints "true"

We are inspecting a by checking it’s constructor, and using the instanceof operator which checks the prototype chain of the object (more on this later). We can see that the constructor of a is the function Object() and that as expected, it is an instance of Object.

Objects defined using the new give us a consistent way to create objects, which are also identified as being of the same instance by the instanceof operator:

// Using a constructor function
function A() {
    this.field = "a";
}
// Inline object creation
var a = new A();
console.info("a's constructor: " + a.constructor) // prints "function A()..."
console.info("a instanceof Object?: " + (a instanceof Object)); // prints "true"
console.info("a instanceof A?: " + (a instanceof A)); // prints "true"

We have now objects of a specific “class”. This is not really a class but something called [[prototype]], which in an internal property of all JavaScript objects which can be accessed using the Object.getPrototypeOf() function. But how do we create prototype chains like we do in OO languages? This can be done in a number of ways. First, by cloning objects using the Object.create method:

// Object cloning using Object.create()
var a = {
    f1: 1
}
var b = Object.create(a);
b.f2 = 2;
var c = Object.create(b);
c.f3 = 3;
console.info(c.f1 + ", "+c.f2+", "+ c.f3); // prints "1, 2, 3"

And while this creates something like inheritance, it behaves really strange when using the instanceof operator:

console.info(b instanceof a); // prints an error because instanceof expect a function as its second argument

This is the place where JavaScript comes out as a very confusing and inconsistent language. The instanceof operator actually checks if the [[prototype]] chain of the first argument contains the prototype property of the second argument (a function). But since we didn’t use a function to create these objects, we can’t use the instanceof operator. Weird…
For this case we can use the Object.getPrototypeOf() function to check the prototype chain, like this:

console.info(Object.getPrototypeOf(c) === b); // prints "true"

But IMHO this is a broken experience. So then, how can we create inheritance in JavaScript while keeping the instanceof operator working? We do this by overriding the prototype property of the constructor function:

function A() {
    f1: 1
};
// no need to override prototype here since it is our base class
var a = new A();
console.info("a instanceof A?: " + (a instanceof A)); // true

function B() {
    this.f2 = 2;
};
B.prototype = new A();
var b = new B();
console.info("b instanceof B?: " + (b instanceof B)); // true
console.info("b instanceof A?: " + (b instanceof A)); // true

function C() {
    this.f3 = 3;
}
C.prototype = new A();
var c = new C();
console.info("c instanceof C?: " + (c instanceof C)); // true
console.info("c instanceof A?: " + (c instanceof A)); // true
console.info("c instanceof B?: " + (c instanceof B)); // false

This works as expected, and while it is not the clearest syntax in the world, it is understandable. And while this works, and it took me a while to get this syntax right, I found that this is not the correct way to do it, as explained by the MDN. Some reasons for this are :

  • Using new to initialize the prototype of the constructor is problematic when the constructor requires parameters, since there are none available when the prototype is set
  • We should replace the prototype.constructor of the constructor (which sets it for all objects created by it) so that if someone, for some strange reason, wants to create an object by referring the constructor from the prototype, he will get the correct constructor

So based on these guidelines, this is how we should create new objects and prototype chains (which is similar to class hierarchies, but not exactly the same):

var A = function() { };
var B = function() { };
B.prototype = Object.create(A.prototype);
B.prototype.constructor = B;
var b = new B();
console.info("b instanceof B?: " + (b instanceof B)); // true
console.info("b instanceof A?: " + (b instanceof A)); // true
console.info("Object.getPrototypeOf(b) === B.prototype?: "+ (Object.getPrototypeOf(b) === B.prototype)); // true

And as you can see, both the instanceof operator and the Object.getPrototypeOf() function behave as expected.

Now that we have this settled, let’s do some properties and functions to our objects and see what happens:

var A = function (v1) {
    this.v1 = v1;
};
A.prototype.p1 = "a";
A.prototype.f1 = function () {
    console.info("In A.f1, p1="+this.p1);
}

var B = function () {
    A.call(this, 2);
};
B.prototype = Object.create(A.prototype);
B.prototype.constructor = B;
B.prototype.p1 = "b";
B.prototype.f2 = function () {
    console.info("In B.f2, p1=" + this.p1);
}

var C = function () {
    B.call(this);
}
C.prototype = Object.create(B.prototype);
C.prototype.constructor = C;
C.prototype.f1 = function () {
    console.info("In C.f1, p1=" + this.p1);
}

var a = new A(1);
console.info("v1="+a.v1);
a.f1(); // prints "In A.f1, p1=a"
var b = new B(); 
b.f1(); // prints "In A.f1, p1=b"
b.f2(); // prints "In B.f2, p1=b"
console.info("v1="+b.v1);
var c = new C();
c.f1(); // prints "In C.f1, p1=b"
c.f2(); // prints "In B.f2, p1=b"
console.info("v1="+c.v1);

We first create the prototype A by defining its constructor (the A function) and adding two properties to its prototype and assign them values (remember, functions in JavaScript are also values). Then we define prototype B which is based on the prototype of A. Of interest here is that we are replacing p1 with a new value, “masking” the value that was defined in A, and we call the parent constructor using the call function, which passes the this context. This is the way parent constructors are called… ugly, but that is how it is done. We then define C based on the prototype of B, and this time change the value of f1. The result of all this can be seen in the output that is printed to the console.

What happens internally is that when a value is referenced in an object, the interpreter first checks if it exists in the object. If not, it goes to the prototype, and then to the prototype of the prototype, until it either finds the value or gets an null prototype.

Continuing after we left of in the previous example, let’s now do something that can’t be done in regular compiled OO languages like C++/C#/Java. We’ll redefine f1 of prototype A, which changes its value for all objects that have A as its prototype (a and b):

A.prototype.f1 = function () {
    console.info("New A.f1, p1=" + this.p1);
}
a.f1(); // prints "New A.f1, p1=a"
b.f1(); // prints "New A.f1, p1=b"
c.f1(); // prints "C.f1, p1=b"

I guess that is enough for the moment. It took me a while to get all of this material inside, but now I think I understand what is happening here. Until next time, happy coding!

Next Tutorial: Statements

Written by vainolo

April 27th, 2015 at 8:02 pm

JavaScript Tutorial – Part 3: Variable Scope and Closures

leave a comment

Previous Tutorial: Variables, Functions, and Objects

Naming is one of the hardest problems in programming. Since there are many things to decide when creating a program, programmers tend to use the same name for variables in many places. And because JavaScript is a very “promiscuous” language, this can cause serious bugs that can be very hard to debug. Therefore it is very important to know what is the scope of the variables we define in our program:

Global Scope

These are variables that you declare outside functions or objects with or without the var keyword, or variables declared inside functions without the var keyword. Let’s look at an example:

a = 1;
b = 2
var c = 3;
console.info("a=" + a + ", b=" + b + ", c=" + c); // prints "a=1, b=2, c=3"
function foo() {
    a = 6;
    var b = 7
    var c = 5;
    d = 8;
    console.info("a=" + a + ", b=" + b + ", c=" + c+", d="+d); // prints "a=6, b=7, c=5, d=8"
}
foo();
console.info("a=" + a + ", b=" + b + ", c=" + c + ", d=" + d); // prints "a=6, b=2, c=3, d=8"

We can see that setting the value of the global variable a inside function foo sets the value also outside the function. This can be prevented by using the var keyword, as done with variable b. Variable c behaves as expected as it is declared both globally and locally (a.k.a masking), therefore changes to the variable are only local. Lastly, variable d is defined inside function foo without the var declaration, therefore becomes a new global variable after the function is invoked.

Function Scope

Variables declared (with the var keyword) inside a function (or an object constructor which is also a function) are scoped to the function and all functions defined inside this function (JavaScript allows us to define functions inside functions, as we will see below). But there are some gotchas that need some investigating. Let’s have an example:

var a = 1;
var b = 2;
var c;
console.info("a=" + a + ", b=" + b+", c="+c); // prints "a=1, b=2, c=undefined"
function foo() {
    var a = 3;
    var c = 4;
    console.info("a=" + a + ", b=" + b + ", c=" + c); // prints "a=3, b=undefined, c=4"
    function bar() {
        var a = 5;
        c = 6;
        console.info("a=" + a + ", b=" + b + ", c=" + c); // prints "a=5, b=7, c=6"
    }
    var b = 7;
    bar();
    console.info("a=" + a + ", b=" + b + ", c=" + c); // prints "a=3, b=7, c=6"
}
foo();
console.info("a=" + a + ", b=" + b + ", c=" + c); // prints "a=1, b=2, c=undefined"

We first define 3 global variables to use in our example. Note that c has been defined but not yet given a value, so the output of our first print statement show it as “undefined” (yea, very confusing that a defined variable is called “undefined” instead of “uninitialized”… Someone is laughing at us here).

Now comes the interesting stuff. When foo is invoked, variables a and c are redefined, masking the global variables, but when we print their value, we also get b=undefined. Wat?. What is happening here is that a few lines below we defined b giving it the value 7. When a function is called, the JavaScript interpreter scans for all variable definitions inside the function and creates for them a variable that is undefined, and then executes the function. Weird, and definitely something to remember.

Moving forward, function bar is defined and executed, with a masking the local a from foo, and the assignment of 6 to c which changes the variable from the closing scope (foo). At the end of the example, we cab see that all variables in the global scope are unchanged, because we masked them inside the functions.

Closures

A closure is a way to tie a function with variables outside of its scope. The closure of a function contains all of the variables that are not defined inside the function and used by it (and are not global). Since JavaScript allows for the definition of variables inside functions, it is very easy to show how this works:

function foo(x) {
    var a = x;
    return function () {
        a = a + 5;
        return a;
    }
}
var bar1 = foo(10);
console.info("a=" + bar1()); // prints "a=15"
var = foo(100);
console.info("a=" + bar2()); // prints "a=105"
console.info("a=" + bar1()); // prints "a=20"
console.info("a=" + bar2()); // prints "a=110"

We defined function foo which returns a function (cool, right?). This internal function uses the value of a defined in the enclosing scope, creating a closure. When we invoke bar, the value of a is already defined an matches the value of the parameter passed to foo. Furthermore, you can see from the output that each time foo is called, a new closure is created with a new value of a.

Awesome.

Next Tutorial: Object Creation and Prototype Chains

Written by vainolo

April 19th, 2015 at 8:54 pm

Posted in Programming

Tagged with , , ,

%d bloggers like this: