Skip to main content

Ivan Teoh

Something personal yet public

On track 1 week 3, we are continuing understanding JavaScript through Douglas Crockford's video 3 and video 4.

Reflection

  1. In Javascript, functions are first class objects. What does it mean to be a first class object? From Wikipedia - First-class_object, first class object is an entity that can be passed as a parameter, returned from a subroutine, or assigned into a variable.
  2. Functions and variables share the same namespace. What does this mean and what important implication does this have? We can have same name for both function and variable. They are the same in JavaScript.
  3. Douglas Crockford equates JavaScript functions with Lambdas, and also mentions that they are a secure construct. Can you do some research and reflect on what he means by 'secure construct'? From the presentation, he said it can constraint the scope.
  4. Can you explain the concept of a closure. Closures got very clear explanation on closure. A "closure" is an expression (typically a function) that can have free variables together with an environment that binds those variables (that "closes" the expression).
  5. What is the difference between a function and a method? A function in an object is called a method.
  6. In Javascript there is no implicit type checking of arguments passed to functions. This could lead to bugs if programmers are not careful about what they pass to functions. If you create a function, how would you protect it from well meaning but careless programmers? One way, we can use function's arguments property to verify on each arguments. When a function is invoked, in addition to its parameters, it also gets a special parameter called arguments. It contains all of the arguments from the invocation. It is an array-like object. We can use arguments.length to verify the total of arguments are passed.
  7. JavaScript functions have implicit access to something called this. this points to different things depending on how the function was created. Can you explain why we need this, and what it represents in different type of functions. From the presentation, this is an extra parameter. Its value depends on the calling form. It also gives methods access to their objects and it is bound at invocation time. If the invocation form is function, functionObject(arguments), then this is the global object. If the invocation form is method, thisObject.methodName(arguments), then this is the object. Finally, if the invocation form is constructor, new functionObject(arguments), this is the new object.
  8. Why doesn't JavaScript have a cast operator? The cast operator converts one type into another. In C, its general form is (type) variable. Because it uses other way, for example using parseInt() function to convert string type to integer type.
  9. What is reflection and why is it easy in JavaScript (you may need to do research to answer this question)? Reflection is the process by which a computer program can observe and modify its own structure and behavior at runtime. Every object is a separate namespace. Use an object to organize your variables and functions.

Homework

Week 3 homework for track 1 are the same as track 2. Here will be exercises 6.1 to 6.5. Track 2 will be showing the answers that is recommended by JSLint.

  • Ex. 6.1: Write a function countZeroes, which takes an array of numbers as its argument and returns the amount of zeroes that occur in it. Use reduce. Then, write the higher-order function count, which takes an array and a test function as arguments, and returns the amount of elements in the array for which the test function returned true. Re-implement countZeroes using this function.

    170-exercise61a.js (Source)

    function forEach(array, action) {
      for (var i = 0; i < array.length; i++)
        action(array[i]);
    }
    
    function reduce(combine, base, array) {
      forEach(array, function (element) {
        base = combine(base, element);
      });
      return base;
    }
    
    function zeroes(a, b) {
        if (b) {
            return a;
        }
        return a + 1;
    }
    
    function countZeroes(numbers) {
        return reduce(zeroes, 0, numbers);
    }
    
    document.write(countZeroes([1, 3, 0, 6, 0, 0, 0])); // 4
    

    Using count.

    170-exercise61b.js (Source)

    function forEach(array, action) {
      for (var i = 0; i < array.length; i++)
        action(array[i]);
    }
    
    function count(array, test) {
        total = 0;
        forEach(array, function (element) {
            if (test(element)) {
                total += 1;
            }
        });
        return total;
    }
    
    function zeroes(a) {
        return !a;
    }
    
    function countZeroes(numbers) {
        return count(numbers, zeroes);
    }
    
    document.write(countZeroes([1, 3, 0, 6, 0, 0, 8, 2])); // 3
    
  • Ex. 6.2: Write a function processParagraph that, when given a paragraph string as its argument, checks whether this paragraph is a header. If it is, it strips of the '%' characters and counts their number. Then, it returns an object with two properties, content, which contains the text inside the paragraph, and type, which contains the tag that this paragraph must be wrapped in, "p" for regular paragraphs, "h1" for headers with one '%', and "hX" for headers with X '%' characters. Remember that strings have a charAt method that can be used to look at a specific character inside them.

    170-exercise62.js (Source)

    function processParagraph(paragraph) {
        // check whether this paragraph is header
        var typeString = 'p';
        var header = 0;
        for (var i = 0; i < paragraph.length; i++) {
            if (paragraph.charAt(i) == '%') {
                header += 1;
            } else {
                break;
            }
        }
    
        if (header) {
            typeString = 'h' + header;
            content = paragraph.substr(header + 1);
        } else {
            content = paragraph.substr(header);
        }
    
    
    
        return {'content': content, 'type': typeString};
    }
    // {'content': 'Language', 'type': 'h2'}
    console.log(processParagraph("%% Language"));
    // {'content': 'A hermit spent ten years writing a program.', 'type': 'p'}
    console.log(processParagraph("A hermit spent ten years writing a program."));
    // {'content': 'The Book of Programming', 'type': 'h1'}
    console.log(processParagraph("% The Book of Programming"));
    
  • Ex. 6.3: Build a function splitParagraph which, given a paragraph string, returns an array of paragraph fragments. Think of a good way to represent the fragments. The method indexOf, which searches for a character or sub-string in a string and returns its position, or -1 if not found, will probably be useful in some way here. This is a tricky algorithm, and there are many not-quite-correct or way-too-long ways to describe it. If you run into problems, just think about it for a minute. Try to write inner functions that perform the smaller actions that make up the algorithm.

    170-exercise63.js (Source)

    function splitParagraph(paragraph) {
        var paragraphs = [];
    
        function spliting(first, last, typeString) {
            while (true)  {
                start = paragraph.indexOf(first, 0);
                if (start == -1) {
                    break;
                }
                end = paragraph.indexOf(last, start + 1);
                if (end == -1) {
                    break;
                }
                // content does not have "*"
                content = paragraph.slice(start, end + 1).slice(1, -1);
                paragraph = paragraph.slice(0,
                                paragraph.charAt(start) == " "? start - 1 :start)
                                .concat(paragraph.slice(end + 1));
                paragraphs.push({'content': content, 'type': typeString});
            }
        }
    
        // emphasised part
        spliting("*", "*", "emphasised");
    
        // footnote
        spliting("{", "}", "footnote");
    
        // normal text
        paragraphs.push({'content': paragraph, 'type': 'normal'});
        return paragraphs;
    }
    
    // [{'content': 'million', 'type': 'emphasised'},
    //  {'content': 'mine is almost a lines', 'type': 'normal'}]
    console.log(splitParagraph("mine is almost a *million* lines"));
    // [{'content': 'Type something!', 'type': 'emphasised'},
    //  {'content': "and shouted '' The student", 'type': 'normal'}]
    console.log(splitParagraph("and shouted '*Type something!*' The student"));
    // [{'content': 'square', 'type': 'emphasised'},
    //  {'content': 'result', 'type': 'emphasised'},
    //  {'content': 'two and then it again, the is already inaccurate!',
    //   'type': 'normal'}]
    console.log(splitParagraph("two and then *square* it again, the *result* is " +
    "already inaccurate!"));
    // [{'content': 'million', 'type': 'footnote'},
    //  {'content': 'mine is almost a lines', 'type': 'normal'}]
    console.log(splitParagraph("mine is almost a {million} lines"));
    // [{'content': 'square', 'type': 'emphasised'},
    //  {'content': 'result', 'type': 'footnote'},
    //  {'content': 'two and then it again, the is already inaccurate!',
    //   'type': 'normal'}]
    console.log(splitParagraph("two and then *square* it again, the {result} is " +
    "already inaccurate!"));
    
  • Ex. 6.4: Looking back at the example HTML document if necessary, write an image function which, when given the location of an image file, will create an img HTML element.

    170-exercise64.js (Source)

    function tag(name, content, attributes) {
      return {name: name, attributes: attributes, content: content};
    }
    
    function image(path) {
      return tag("img", [], {src: path});
    }
    
  • Ex. 6.5: Write a function renderFragment, and use that to implement another function renderParagraph, which takes a paragraph object (with the footnotes already filtered out), and produces the correct HTML element (which might be a paragraph or a header, depending on the type property of the paragraph object). This function might come in useful for rendering the footnote references:

    170-exercise65a.js (Source)

    function footnote(number) {
      return tag("sup", [link("#footnote" + number,
                              String(number))]);
    }
    

    A sup tag will show its content as 'superscript', which means it will be smaller and a little higher than other text. The target of the link will be something like "#footnote1". Links that contain a '#' character refer to 'anchors' within a page, and in this case we will use them to make it so that clicking on the footnote link will take the reader to the bottom of the page, where the footnotes live. The tag to render emphasized fragments with is em, and normal text can be rendered without any extra tags.

    170-exercise65b.js (Source)

    function splitParagraph(paragraph) {
        var paragraphs = [];
    
        function spliting(first, last, typeString) {
            while (true)  {
                start = paragraph.indexOf(first, 0);
                if (start == -1) {
                    break;
                }
                end = paragraph.indexOf(last, start + 1);
                if (end == -1) {
                    break;
                }
                // content does not have "*"
                content = paragraph.slice(start, end + 1).slice(1, -1);
                paragraph = paragraph.slice(0,
                                paragraph.charAt(start) == " "? start - 1 :start)
                                .concat(paragraph.slice(end + 1));
                paragraphs.push({'content': content, 'type': typeString});
            }
        }
    
        // emphasised part
        spliting("*", "*", "emphasised");
    
        // footnote
        spliting("{", "}", "footnote");
    
        // normal text
        paragraphs.push({'content': paragraph, 'type': 'normal'});
        return paragraphs;
    }
    
    function forEach(array, action) {
      for (var i = 0; i < array.length; i++)
        action(array[i]);
    }
    
    function map(func, array) {
      var result = [];
      forEach(array, function (element) {
        result.push(func(element));
      });
      return result;
    }
    
    function tag(name, content, attributes) {
      return {name: name, attributes: attributes, content: content};
    }
    
    function link(target, text) {
      return tag("a", [text], {href: target});
    }
    
    function footnote(number) {
      return tag("sup", [link("#footnote" + number,
                              String(number))]);
    }
    
    function renderFragment(fragment) {
        var content;
        switch (fragment.type) {
            case "emphasised":
                content = tag("em", [fragment.content]);
                break;
            case "footnote":
                content = footnote(fragment.content);
                break;
            //case "normal":
            default:
                content = fragment.content;
                break;
        }
        return content;
    }
    
    // {'content': 'A hermit spent ten years writing a program.', 'type': 'p'}
    // {'content': 'two and then *square* it again, the {result} is already
    // inaccurate!', 'type': 'p'}
    function renderParagraph(paragraph) {
        // [{'content': 'square', 'type': 'emphasised'},
        //  {'content': 'result', 'type': 'footnote'},
        //  {'content': 'two and then it again, the is already inaccurate!',
        //   'type': 'normal'}]
        fragments = splitParagraph(paragraph.content);
        return tag(paragraph.type, map(renderFragment, fragments));
    }
    
    console.log(renderParagraph({'content': 'two and then *square* it again, the ' +
    '{result} is already inaccurate!', 'type': 'p'}));
    

Oh. We know the dish does not looked like gnocchi. It is our first time to make them. We spent around two hours to make both pesto and gnocchi. We made the pesto first. We believed we were overdosing the cheese making the pesto very think to blend in our low power food processor. It made us put more olive oil. At last, it turned out taste good. Next is gnocchi. Since we are so hungry, we simply cut the pasta into big square shape. After boiling, it turned even bigger. In the end, it was a good experience. The recipe was from our favourite food blog, King Arthur Flour - Baking Banter. Our mouth still full of garlic smell, even after cleaning our teeth and mouth washing with mouth rinse. We were still deciding whether we should go out after this. We don't want to scary away people with our garlic smell. We guess tonight is not a good night to make this dish.

For track 2 on week 2, I basically need to read chapter 4 and 5 on Eloquent JavaScript.

Reflection

  • It is tough to explain Objects and Arrays to my grandmother.
  • If I would pick either bad code or a naughty browser for my best practice for errors, I would be bad code.

Homework

  • Ex. 4.1: The solution for the cat problem talks about a 'set' of names. A set is a collection of values in which no value may occur more than once. If names are strings, can you think of a way to use an object to represent a set of names? Show how a name can be added to this set, how one can be removed, and how you can check whether a name occurs in it.

    167-exercise41.js (Source)

    var cat = {}; // a 'set' of names
    cat['Red Lion'] = {'colour': 'grey', 'size': 46}; // a name is added to this set
    cat['Doctor Hobbles'] = {'colour': 'white', 'size': 15};
    cat['Little Iroquois'] = {'colour': 'yellow', 'size': 30};
    delete cat['Doctor Hobbles']; // a name is removed from this set
    if ('Red Lion' in cat) { // check whether a name occurs in this set.
        alert('you have "Red Lion" cat.');
    }
    
  • Ex. 4.2: Write a function range that takes one argument, a positive number, and returns an array containing all numbers from 0 up to and including the given number. An empty array can be created by simply typing []. Also remember that adding properties to an object, and thus also to an array, can be done by assigning them a value with the = operator. The length property is automatically updated when elements are added.

    167-exercise42.js (Source)

    function range(num) {
        var list = [];
        for (var i = 0; i <= num; i++) {
            list[i] = i;
        }
        return list;
    }
    document.write(range(5));
    
  • Ex. 4.3: split and join are not precisely each other's inverse. string.split(x).join(x) always produces the original value, but array.join(x).split(x) does not. Can you give an example of an array where .join(" ").split(" ") produces a different value?

    167-exercise43.js (Source)

    var sentence = ["We are", "family"];
    sentence.join(" ").split(" ");
    
  • Ex. 4.4: Write a function called startsWith that takes two arguments, both strings. It returns true when the first argument starts with the characters in the second argument, and false otherwise.

    167-exercise44.js (Source)

    function startsWith (firstString, secondString) {
        var result = false;
        firstLength = firstString.length;
        secondLength = secondString.length;
        if (secondLength > firstLength)
            return result;
    
        if (firstString.slice(0, secondLength) == secondString)
            result = true;
        return result;
    }
    document.write(startsWith("oranges", "orange")); // true
    document.write(startsWith("peach", "orange"));   // false
    document.write(startsWith("peaches", "grape"));  // false
    
  • Ex. 4.5: Can you write a function catNames that takes a paragraph as an argument and returns an array of names? Strings have an indexOf method that can be used to find the (first) position of a character or sub-string within that string. Also, when slice is given only one argument, it will return the part of the string from the given position all the way to the end. It can be helpful to use the console to 'explore' functions. For example, type "foo: bar".indexOf(":") and see what you get.

    167-exercise45.js (Source)

    function catNames(paragraph) {
        var result = [];
        var colon = paragraph.indexOf(":");
        allCat = paragraph.slice(colon + 1);
        names = allCat.split(",");
        for (var i = 0; i < names.length; i++) {
            var catName = names[i].split("");
            var startName;
            var endName;
            // Trims whitespace from the left side of the string.
            for (var j = 0; j < catName.length; j++) {
                startName = j;
                if (catName[j] != " ")
                    break;
            }
            // Trims whitespace from the right side of the string.
            for (var k = catName.length - 1; k > -1; k--) {
                endName = k;
                if (catName[k] != " ")
                    break;
            }
            result.push(names[i].slice(startName, endName+1));
        }
        return result;
    }
    var paragraph = "born 05/04/2006 (mother Lady Penelope): Red Lion, Doctor" +
      "Hobbles the 3rd, Little Iroquois";
    document.write(catNames(paragraph));
    
  • Ex. 4.6: The date part, "died 27/04/2006: Black Leclère", is always in the exact same place of a paragraph. How convenient. Write a function extractDate that takes such a paragraph as its argument, extracts the date, and returns it as a date object.

    167-exercise46.js (Source)

    function extractDate(paragraph) {
        var colon = paragraph.indexOf(":");
        var space = paragraph.indexOf(" ");
        var allDate = paragraph.slice(space + 1, colon);
        var dates = allDate.split("/");
        var day = dates[0];
        var month = dates[1];
        var year = dates[2];
        var result = new Date(year, month-1, day);
        return result;
    }
    var paragraph = "died 27/04/2006: Black Leclère";
    document.write(extractDate(paragraph));
    
  • Ex. 4.7: The thing that extractMother does can be expressed in a more general way. Write a function between that takes three arguments, all of which are strings. It will return the part of the first argument that occurs between the patterns given by the second and the third arguments. So between("born 15/11/2003 (mother Spot): White Fang", "(mother ", ")") gives "Spot". between("bu ] boo [ bah ] gzz", "[ ", " ]") returns "bah". To make that second test work, it can be useful to know that indexOf can be given a second, optional parameter that specifies at which point it should start searching.

    167-exercise47.js (Source)

    function between(paragraph, firstPattern, secondPattern) {
        var start = paragraph.indexOf(firstPattern) + firstPattern.length;
        var end = paragraph.indexOf(secondPattern, start);
        return paragraph.slice(start, end);
    }
    document.write(between("born 15/11/2003 (mother Spot): White Fang",
      "(mother ", ")")); // "Spot"
    document.write(between("bu ] boo [ bah ] gzz", "[ ", " ]")); // "bah"
    
  • Ex. 4.8: The formatDate function used by catInfo does not add a zero before the month and the day part when these are only one digit long. Write a new version that does this.

    167-exercise48.js (Source)

    function formatDate(date) {
        var month = date.getMonth() + 1;
        var day = date.getDate();
      return ((day < 10)? ("0" + day) : day) +
             "/" + ((month < 10)? ("0" + month) : month) +
             "/" + date.getFullYear();
    }
    
    document.write(formatDate(new Date(2010, 11, 25))); // "25/12/2010"
    document.write(formatDate(new Date(2011, 1, 4))); // "04/02/2011"
    
  • Ex. 4.9: Write a function oldestCat which, given an object containing cats as its argument, returns the name of the oldest living cat.

    167-exercise49.js (Source)

    function oldestCat(cats) {
        var cat;
        var oldest;
        for (var name in cats) {
            if (!("death" in cats[name]) && !oldest || (oldest > cats[name].birth))
            {
                oldest = cats[name].birth;
                cat = cats[name].name;
            }
        }
      return cat;
    }
    var cats = {"Spot": {name:"Spot", birth: new Date(1997, 2, 5),
                mother: "Yellow"},
                "White": {name:"White", birth: new Date(1998, 7, 4),
                mother: "Zebra"},
                "Grey": {name:"Grey", birth: new Date(1996, 6, 3),
                mother: "Kitten"}};
    document.write(oldestCat(cats)); // "Grey"
    
  • Ex. 4.10: Extend the range function from exercise 4.2 to take a second, optional argument. If only one argument is given, it behaves as earlier and produces a range from 0 to the given number. If two arguments are given, the first indicates the start of the range, the second the end.

    167-exercise410.js (Source)

    function range(num, start) {
        var list = [];
        if (arguments.length < 2) {
            for (var i = 0; i <= num; i++) {
                list[i] = i;
            }
        } else {
            for (var x = 0, y = num; y <= start; x++, y++) {
                list[x] = y;
            }
        }
        return list;
    }
    document.write(range(5)); // 0, 1, 2, 3, 4, 5
    document.write(range(2, 5)); // 2, 3, 4, 5
    
  • Ex. 4.11: You may remember this line of code from the introduction: print(sum(range(1, 10))); We have range now. All we need to make this line work is a sum function. This function takes an array of numbers, and returns their sum. Write it, it should be easy.

    167-exercise411.js (Source)

    function range(num, start) {
        var list = [];
        if (arguments.length < 2) {
            for (var i = 0; i <= num; i++) {
                list[i] = i;
            }
        } else {
            for (var x = 0, y = num; y <= start; x++, y++) {
                list[x] = y;
            }
        }
        return list;
    }
    function sum(numbers) {
        result = 0;
        for (var i = 0; i < numbers.length; i++) {
            result += numbers[i];
        }
        return result;
    }
    document.write(sum(range(1, 10))); // 55
    

On track 1 week 2, we are continuing understanding JavaScript through Douglas Crockford's video as below and chapter 3 on functions, from Eloquent Javascript.

Reflection

  1. Why do languages provide the switch statement, when we can achieve the same thing with multiple if... elseif statements? Show one example of how you might use the switch statement. According to the presentation, switch statement have it's own advantages. The switch value does not need to be a number. It can be a string. The case values can be expressions too.

    166-reflection1.js (Source)

    switch (expression) {
        case 'a':
        case 'b':
        case 'c':
            alphabet();
            break;
        default:
            nonAlphabet();
    }
    
  2. What is encapsulation, and what do functions encapsulate? In simple words, encapsulation means information hiding. The functions encapsulate local variables and functions that are created in side the functions.

  3. What is a pure function? Is the function show() provided in Eloquent Javascript a pure function? According to the book, the defining properties of pure functions are that they always return the same value when given the same arguments, and never have side effects. They take some arguments, return a value based on these arguments, and do not monkey around with anything else. The function show() is not a pure function as it is not self-sufficient.

  4. What do we mean when we say a variable in a function is shadowing a top level variable? It means the local function variable have a same name with a top level variable. When looking up a variable inside a function, the local environment is checked first, and only if the variable does not exist there is it looked up in the top-level environment. This makes it possible for variables inside a function to 'shadow' top-level variables that have the same name.

  5. A recursive function, must have some sort of an end condition. Why would we get a "out of stack space" error message if a recursive function does not have an end condition? According to the book, when a recursive function is called, control is given to the body of that function. When that body returns, the code that called the function is resumed. While the body is running, the computer must remember the context from which the function was called, so that it knows where to continue afterwards. The place where this context is stored is called the stack. This stack requires space in the computer's memory to be stored. When the stack grows too big, the computer will give up with a message like "out of stack space" or "too much recursion".

  6. Reflect about the difference between object inheritance and class inheritance According to the presentation, some languages have classes, methods, constructors, and modules. JavaScript's functions do the works of all of those. Instead of class inheritance, JavaScript has object inheritance. In other words for object inheritance is prototype inheritance. It accomplishes the same things, but differently. It offers greater expressive power. Instead of organizing objects into rigid classes, new objects can be made that are similar to existing objects, and then customized. Object customization is a lot less work than making a class, and less overhead, too. One of the keys is the object(o) function. The other key is function. The object(o) function makes a new empty object with a link to object to. Refer to the Douglas Crockford - inheritance for more classical inheritance in JavaScript.

  7. What is object augmentation, and how do we do it? According to the Douglas Crockford - inheritance, in the static object-oriented languages, if you want an object which is slightly different than another object, you need to define a new class. In JavaScript, you can add methods to individual objects without the need for additional classes. This has enormous power because you can write far fewer classes and the classes you do write can be much simpler. New members can be added to any object by simple assignment, for example, myobject[name] = value;

  8. There is a way to add a method to String, such as any new String we create will have that augmented method (this is a bit different from object augmentation). How would you do this? Using linkage.

  9. What is garbage collection? According to JavaScript: The Definitive Guide, 4th Edition, JavaScript uses garbage collection to reclaim the memory occupied by strings, objects, arrays, and functions that are no longer in use. This frees you, the programmer, from having to explicitly deallocate memory yourself and is an important part of what makes JavaScript programming easier than, say, C programming. A key feature of garbage collection is that the garbage collector must be able to determine when it is safe to reclaim memory. Obviously, it must never reclaim values that are still in use and should collect only values that are no longer reachable; that is, values that cannot be referred to through any of the variables, object properties, or array elements in the program.

  10. What is the difference between an array and an object? According to the presentation, array inherits from object. The indexes are converted to strings and used as names for retrieving values. Arrays, unlike objects, have a special length member. Arrays allows use of the traditional for statement. Only use for..in for objects and not arrays. The dot notation also should only use for objects and not arrays. Use objects when the names are arbitrary strings. On the other hands, use arrays when the names are sequential integers. We can't use arrays as prototypes as the objects produced this way does not have array nature. It will inherit the array's values and methods, but not its length. We can augment an individual array by assigning a method to it. This works as arrays are objects. We also can augment all arrays by assigning the methods to Array.prototype.

Homework

  1. Exercises 3.1 from chapter 3 of Eloquent Javascript: Write a function called absolute, which returns the absolute value of the number it is given as its argument. The absolute value of a negative number is the positive version of that same number, and the absolute value of a positive number (or zero) is that number itself.

    166-homework1.js (Source)

    function absolute(number) {
        if (number < 0)
            return -number;
        return number;
    }
    
  2. Exercises 3.2 from chapter 3 of Eloquent Javascript: Write a function greaterThan, which takes one argument, a number, and returns a function that represents a test. When this returned function is called with a single number as argument, it returns a boolean: true if the given number is greater than the number that was used to create the test function, and false otherwise.

    166-homework2.js (Source)

    function greaterThan(number1) {
        function test(number2) {
            return number2 > number1;
        }
        return test;
    }
    
    var greaterThanTwenty = greaterThan(20);
    alert(greaterThanTwenty(52));
    alert(greaterThanTwenty(10));
    
  3. Shown below is some code which does something useful. The function 'iterateAndOperate' is the one which accomplishes something useful. The remaining code helps this function. Try to understand what the function accomplishes and solve the problems in part a, b, and c. The code can be done inside the console in Javascript, or in the web browser. Please see this comment, for hints on how you may do it inside a web page(remember, HTML has special codes for spaces and newlines).

    166-homework3.js (Source)

    //A constant to hold the String "null". To be used in typeof checks
    NULL_VAL = "null";
    //A constant to hold the String "undefined". To be used in typeof checks
    UNDEFINED_VAL = "undefined";
    
    /*
     * This function checks if the specified parameter is null or undefined
     * @param something The specified parameter to check for a null or undefined
     * value
     * @param name The name of the parameter. This will be used in the error message
     * If the value 'something' is found to be null or undefined, then this method
     * will throw an Error
     */
    function checkNullOrUndefined(something, name) {
     if(UNDEFINED_VAL == typeof(something)) {
     throw new Error(name + " cannot be undefined");
      }
      if(NULL_VAL == typeof(something)) {
        throw new Error(name + " cannot be null");
      }
    }
    
    
    /*
     * This function accepts an array object and a function reference.
     * It iterates through the array and invokes the specified function
     * for every element of the array. In each invocation the current
     * array element is given to the function as a parameter.
     * @param arr The array
     * @param func The function to invoke for every element of the array
     * This method does not return any specific value.
     * This method throws an Error if 'arr' is null, undefined, or is not an array
     * This method throws an Error if 'func' is null, undefined, or is not a
     * function
     */
    function iterateAndOperate(arr, func) {
      checkNullOrUndefined(arr, "arr");
      checkNullOrUndefined(func, "func");
      // Verify that arr is an array
      if(!(arr instanceof Array)) {
        throw new Error("arr does not seem to be an array");
      }
      // Verify that arr is an array
      if("function" != typeof(func)) {
        throw new Error("func is not a function");
      }
      for(var i=0; i<arr.length; i++) {
        func(arr[i]);
      }
    }
    
    1. Use the function iterateAndOperate to draw an image which looks like this

      166-homework31.txt (Source)

      ++++@++++
      +++@@@+++
      ++@@@@@++
      +++@@@+++
      ++++@++++
      

      Code:

      166-homework31.html (Source)

      <!DOCTYPE HTML>
      <html lang="en">
      <head>
          <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
          <title>JavaScript 101</title>
          <script type="text/javascript">
              function load()
              {
                  // A constant to hold the String "null". To be used in typeof checks
                  NULL_VAL = "null";
                  // A constant to hold the String "undefined". To be used in typeof
                  // checks
                  UNDEFINED_VAL = "undefined";
      
                  /*
                   * This function checks if the specified parameter is null or
                   * undefined
                   * @param something The specified parameter to check for a null or
                   * undefined value
                   * @param name The name of the parameter. This will be used in the
                   * error message
                   * If the value 'something' is found to be null or undefined, then
                   * this method
                   * will throw an Error
                   */
                  function checkNullOrUndefined(something, name) {
                   if(UNDEFINED_VAL == typeof(something)) {
                   throw new Error(name + " cannot be undefined");
                    }
                    if(NULL_VAL == typeof(something)) {
                      throw new Error(name + " cannot be null");
                    }
                  }
      
      
                  /*
                   * This function accepts an array object and a function reference.
                   * It iterates through the array and invokes the specified function
                   * for every element of the array. In each invocation the current
                   * array element is given to the function as a parameter.
                   * @param arr The array
                   * @param func The function to invoke for every element of the array
                   * This method does not return any specific value.
                   * This method throws an Error if 'arr' is null, undefined, or is
                   * not an array
                   * This method throws an Error if 'func' is null, undefined, or is
                   * not a function
                   */
                  function iterateAndOperate(arr, func) {
                    checkNullOrUndefined(arr, "arr");
                    checkNullOrUndefined(func, "func");
                    // Verify that arr is an array
                    if(!(arr instanceof Array)) {
                      throw new Error("arr does not seem to be an array");
                    }
                    // Verify that arr is an array
                    if("function" != typeof(func)) {
                      throw new Error("func is not a function");
                    }
                    for(var i = 0; i<arr.length; i++) {
                      func(arr[i]);
                    }
                  }
      
                  function draw(symbol) {
                      function plusDraw(sign) {
                          for (var j = 0; j < sign; j++) {
                              document.write("+");
                          }
                      }
                      var total = 9;
                      var plus = (total - symbol)/2;
                      plusDraw(plus);
                      for (var j = 0; j < symbol; j++) {
                          document.write("@");
                      }
                      plusDraw(plus);
                      document.write("<br />");
                  }
                  iterateAndOperate([1, 3, 5, 3, 1], draw);
              }
          </script>
      </head>
      <body onload="load()">
      </body>
      </html>
      
    2. Use the function iterateAndOperate to draw a triangle which looks like this

      166-homework32.txt (Source)

      *
      ***
      *****
      ***
      *
      

      Code:

      166-homework32.html (Source)

      <!DOCTYPE HTML>
      <html lang="en">
      <head>
          <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
          <title>JavaScript 101</title>
          <script type="text/javascript">
              function load()
              {
                  // A constant to hold the String "null". To be used in typeof checks
                  NULL_VAL = "null";
                  // A constant to hold the String "undefined". To be used in typeof
                  // checks
                  UNDEFINED_VAL = "undefined";
      
                  /*
                   * This function checks if the specified parameter is null or
                   * undefined
                   * @param something The specified parameter to check for a null or
                   * undefined value
                   * @param name The name of the parameter. This will be used in the
                   * error message
                   * If the value 'something' is found to be null or undefined, then
                   * this method
                   * will throw an Error
                   */
                  function checkNullOrUndefined(something, name) {
                   if(UNDEFINED_VAL == typeof(something)) {
                   throw new Error(name + " cannot be undefined");
                    }
                    if(NULL_VAL == typeof(something)) {
                      throw new Error(name + " cannot be null");
                    }
                  }
      
      
                  /*
                   * This function accepts an array object and a function reference.
                   * It iterates through the array and invokes the specified function
                   * for every element of the array. In each invocation the current
                   * array element is given to the function as a parameter.
                   * @param arr The array
                   * @param func The function to invoke for every element of the array
                   * This method does not return any specific value.
                   * This method throws an Error if 'arr' is null, undefined, or is
                   * not an array
                   * This method throws an Error if 'func' is null, undefined, or is
                   * not a function
                   */
                  function iterateAndOperate(arr, func) {
                    checkNullOrUndefined(arr, "arr");
                    checkNullOrUndefined(func, "func");
                    // Verify that arr is an array
                    if(!(arr instanceof Array)) {
                      throw new Error("arr does not seem to be an array");
                    }
                    // Verify that arr is an array
                    if("function" != typeof(func)) {
                      throw new Error("func is not a function");
                    }
                    for(var i = 0; i < arr.length; i++) {
                      func(arr[i]);
                    }
                  }
      
                  function draw(symbol) {
                      for (var j = 0; j < symbol; j++) {
                          document.write("*");
                      }
                      document.write("<br />");
                  }
      
                  iterateAndOperate([1, 3, 5, 3, 1], draw);
              }
          </script>
      </head>
      <body onload="load()">
      </body>
      </html>
      
    3. In your code which invokes iterateAndOperate() without any parameters, as shown. An Exception will be thrown. Catch the Exception show an Alert to the user with a user friendly error message.

      166-homework33.html (Source)

      <!DOCTYPE HTML>
      <html lang="en">
      <head>
          <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
          <title>JavaScript 101</title>
          <script type="text/javascript">
              function load()
              {
                  // A constant to hold the String "null". To be used in typeof checks
                  NULL_VAL = "null";
                  // A constant to hold the String "undefined". To be used in typeof
                  // checks
                  UNDEFINED_VAL = "undefined";
      
                  /*
                   * This function checks if the specified parameter is null or
                   * undefined
                   * @param something The specified parameter to check for a null or
                   * undefined value
                   * @param name The name of the parameter. This will be used in the
                   * error message
                   * If the value 'something' is found to be null or undefined, then
                   * this method
                   * will throw an Error
                   */
                  function checkNullOrUndefined(something, name) {
                      if(UNDEFINED_VAL == typeof(something)) {
                          throw new Error(name + " cannot be undefined");
                      }
                      if(NULL_VAL == typeof(something)) {
                          throw new Error(name + " cannot be null");
                      }
                  }
      
      
                  /*
                   * This function accepts an array object and a function reference.
                   * It iterates through the array and invokes the specified function
                   * for every element of the array. In each invocation the current
                   * array element is given to the function as a parameter.
                   * @param arr The array
                   * @param func The function to invoke for every element of the array
                   * This method does not return any specific value.
                   * This method throws an Error if 'arr' is null, undefined, or is
                   * not an array
                   * This method throws an Error if 'func' is null, undefined, or is
                   * not a function
                   */
                  function iterateAndOperate(arr, func) {
                      try {
                          checkNullOrUndefined(arr, "arr");
                          checkNullOrUndefined(func, "func");
                          // Verify that arr is an array
                          if(!(arr instanceof Array)) {
                              throw new Error("arr does not seem to be an array");
                          }
                          // Verify that arr is an array
                          if("function" != typeof(func)) {
                              throw new Error("func is not a function");
                          }
                          for(var i = 0; i < arr.length; i++) {
                              func(arr[i]);
                          }
                      }
                      catch(e){
                       alert('An error has occurred: '+e.message)
                      }
                  }
                  iterateAndOperate();
              }
          </script>
      </head>
      <body onload="load()">
      </body>
      </html>
      

This post is a reply for the Javascript: 101 Week 1 Track 1. Mainly answering questions for reflection and homework.

Reflection

  • Java was not suitable to be embedded in a browser because it need to be typically compiled and run on Java Virtual Machine (JVM). On the other hand, JavaScript typically relies on a run-time environment.
  • When using the parseInt() method, it is recommended to provide the radix as it stops at the first non-digit character and if the first digit is zero, it is allowed to interpret as octal constant, for example, parseInt("08") == 0.
  • Type is a way to represent the data in computer memory. It is useful in writing programs as it can be keep in the way as we want efficiently.
  • We lose precision when performing operations with decimal numbers in JavaScript because of the limitation of number representation in computer memory. It can be a problem when we are dealing money by dividing with odd number, such as 3.
  • The following operation produces the given result 115 * 4 - 4 + 88 / 2 = 500 as multiplication and division are calculating first before addition and subtraction. After multiplication and division, the equation will be 460 - 4 + 44.
  • The purpose of typeof 4.5 is to returning the type of 4.5 in string format, which is number in this case. On the other hand, typeof (typeof 4.5) will return string because typeof function is returning string type. There is not special type of data type in JavaScript.

Homework

Answer for exercises 2.1 - 2.6 from chapter 2 of Eloquent Javascript, please refer to Javascript: 101 Week 1 Track 2.

Example that shows a valid use of the 'guard' and 'default' operators in JavaScript.

165-exercise.js (Source)

function stringGuess(aString) {
    // 'default' operator
    var checkString = aString || "aString is falsy value.";
    // 'guard' operator
    if (checkString && checkString.length)
        return checkString;
    return "aString is not a string";
}

var man = 0;
alert(stringGuess(man));
alert(stringGuess(52));
alert(stringGuess("10"));

This post is a reply for the Javascript: 101 Week 1 Track 2. Mainly answering questions for reflection and homework.

Reflection

  • Type is a way to represent the data in computer memory. It is useful in writing programs as it can be keep in the way as we want efficiently.
  • We lose precision when performing operations with decimal numbers in JavaScript because of the limitation of number representation in computer memory. It can be a problem when we are dealing money by dividing with odd number, such as 3.
  • The following operation produces the given result 115 * 4 - 4 + 88 / 2 = 500 as multiplication and division are calculating first before addition and subtraction. After multiplication and division, the equation will be 460 - 4 + 44.
  • A backslash character in a String is to indicate the next character is special, escape character.
  • The purpose of typeof 4.5 is to returning the type of 4.5 in string format, which is number in this case. On the other hand, typeof (typeof 4.5) will return string because typeof function is returning string type. There is not special type of data type in JavaScript.
  • The variables that might be created in the browsers environment when it loads a page with JavaScript in it are document and window.
  • Dear grandma, values are people, variables are house, and control flow is road that moving people from one house to another house.
  • Functions are groups of code that can be used whenever we want. We need them whenever we want to use it in many places. It is to reduce man made mistake and our life easy.

Homework

Exercises 2.1

164-exercise21.js (Source)

(4 >= 6 || "grass" != "green") && !(12 * 2 == 144 && true)

It is true. As (false || true) && !(false && true).

Exercises 2.2

Write a program that calculates and shows the value of 210 (2 to the 10th power).

164-exercise22.js (Source)

var total = 2;
var count = 1;
while (count < 10) {
    total = total * 2;
        count = count + 1;
}
alert(total);

Exercises 2.3

With some slight modifications, the solution to the previous exercise can be made to draw a triangle.

164-exercise23.js (Source)

var triangle = "";
var line = 0;
while (line < 10) {
    var count = 0;
        line = line + 1;
        hash = "";
        while (count < line) {
            hash = hash + "#";
            count = count + 1;
        }
        triangle = triangle + hash + '\n';
}
alert(triangle);

Exercises 2.4

Rewrite the solutions of the previous two exercises to use for instead of while.

From Exercises 2.3

164-exercise24a.js (Source)

for (var total = 2, count = 1; count < 10; count++) {
    total = total * 2;
}
alert(total);

From Exercises 2.4

164-exercise24b.js (Source)

for (var line = 0, triangle = ""; line < 10; line++) {
    for (var count = 0, hash = ""; count <= line; count++) {
        hash = hash + "#";
    }
    triangle = triangle + hash + '\n';
}
alert(triangle);

Exercises 2.5

Write a program to ask yourself, using prompt, what the value of 2 + 2 is. If the answer is "4", use alert to say something praising. If it is "3" or "5", say "Almost!". In other cases, say something mean.

164-exercise25.js (Source)

var theNumber = prompt('What the value of 2 + 2 is?', '');
if (theNumber == '4')
    alert('Correct! Well done.');
else if (theNumber == '3' || theNumber == '5')
    alert('Almost!');
else
    alert('Ops! Please try again!');

Exercises 2.6

Add a while and optionally a break to your solution for the previous exercise, so that it keeps repeating the question until a correct answer is given.

164-exercise26.js (Source)

while (true) {
    var theNumber = prompt('What the value of 2 + 2 is?', '');
    if (theNumber == '4') {
        alert('Correct! Well done.');
        break;
    }
    else if (theNumber == '3' || theNumber == '5')
        alert('Almost!');
    else
        alert('Ops! Please try again!');
}

Exercises 3.1

Write a function called absolute, which returns the absolute value of the number it is given as its argument. The absolute value of a negative number is the positive version of that same number, and the absolute value of a positive number (or zero) is that number itself.

164-exercise31.js (Source)

function absolute(number) {
    if (number < 0)
        return -number;
    return number;
}

Exercises 3.2

Write a function greaterThan, which takes one argument, a number, and returns a function that represents a test. When this returned function is called with a single number as argument, it returns a boolean: true if the given number is greater than the number that was used to create the test function, and false otherwise.

164-exercise32.js (Source)

function greaterThan(number1) {
    function test(number2) {
        return number2 > number1;
    }
    return test;
}

var greaterThanTwenty = greaterThan(20);
alert(greaterThanTwenty(52));
alert(greaterThanTwenty(10));

Writing this post after watching the video below is the first task of signing up JavaScript 101. I knew about this video long time ago. Only today, I really pay 100% attention on what Yahoo! JavaScript Architect Douglas Crockford say in Douglas Crockford - "The JavaScript Programming Language" 1 of 4.

This post is mainly about what I learned from this video. Here there are in point form:

  • Most of the JavaScript books are bad reference. He only recommended JavaScript: The Definitive Guide, Fifth Edition by David Flanagan, which is better reference.
  • Key ideas: load and go delivery, loose typing, objects as general containers, prototype inheritance, lambda, and linkage through global variable.
  • Value: numbers, strings, booleans, objects, null and undefined.
  • numbers: only one number type, which means there is no integer type and no floating point type.
  • NaN: it is a number. Remember that it does not equal to NaN.
  • null: it isn't anything.
  • undefined: default value for variable, parameters
  • Falsey value: false, null, undefined, "" (empty string), 0, NaN
  • Truthy value: "0", "false", object
  • All keywords are generally lower case.
  • == and != can do type coercion, so better use === and !== which do not do type coercion
  • Logical && is a guard operator. If first operand is truthy, then result is second operand, else result is first operand. For example, return a && a.member;
  • Logical || is a default operator. If first operand is truthy, then result is first operand, else result is second operand. For example, var last = input || nr_items;
  • Logical !! produces booleans value of truthy or falsey value. For example, !!"0" is true
  • Bitwise operators convert the operand to a 32-bit signed integer, and turn the result back into 64-bit floating point.

The second task is writing a simple JavaScript program which will print the sum of 2+2 and display the result in an alert window in the browser. I have to create an HTML page and put the JavaScript code within that page, so it executes when the page loads.

163-index.html (Source)

<!DOCTYPE HTML>
<html lang="en">
<head>
    <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
    <title>JavaScript 101</title>
    <script type="text/javascript">
        function load()
        {
            var total = 2 + 2;
            alert(total + '');
        }
    </script>
</head>
<body onload="load()">
</body>
</html>

Tonight we cooked rice pudding. It is different from what I know. Rice does not have to be savoury. It can be cook as dessert too. We used lemon and orange rinds with cinnamon sticks as the pudding favours. Rice pudding main ingredients are rice, milk and sugar. We garnished it with sultanas, butter and nutmeg.

References