UNB/ CS/ David Bremner/ teaching/ cs2613/ labs/ CS2613 Lab 10

Background

JavaScript Objects

Time
10 minutes
Activity
Demo / discussion

JavaScript objects are quite different from Java objects; in particular it is possible (and idiomatic) to use JavaScript objects without any concept of class. JavaScript objects are conceptually similar to (mutable) hashtables in Racket.

> x={ apple: 1}
> x['pear']=2
> x
> x.apple === x['apple']

The last line demonstrates so called property notation that we have already been using. A method in javascript is just a property that is assigned to a function

> obj = {}
> obj.hello = function () { console.log("hello world\n") }
> obj.hello()
> obj['hello']()

Deep Comparison

Time
20 minutes
Activity
Small groups

Follow the Deep Comparison Exercise to write a function deepEqual that passes the following tests. Jasmine uses something very similar for the toEqual matcher used below. Coming from Racket this is a bit disappointing, since the built in equal? function can already do these kinds of comparisons.

describe("equal", function () {
    var obj = {here: {is: "an"}, object: 2};
    it("self", function () {
        expect(deepEqual(obj,obj)).toBe(true);
    });
    it("null", function () {
        expect(deepEqual(null,null)).toBe(true);
    });

    it("different", function () {
        expect(deepEqual(obj, {here: 1, object: 2})).toBe(false);
    });
    it("equivalent", function () {
        expect(deepEqual(obj, {here: {is: "an"}, object: 2})).toBe(true);
    });
});

JavaScript Arrays

Time
20 minutes
Activity
Small groups

JavaScript supports arrays. They are actually implimented as objects, which leads to some slightly surprising behaviour:

> x=[]
> x[10]=1
> x
> x["10"] === x[10]

Follow the (first part of the) Sum of a Range Exercise to write a range function that passes the following tests.

describe("range", function () {
    it("empty", function () {
        expect(array.range(2,1)).toEqual([]);
    });
    it("single", function () {
        expect(array.range(2,2)).toEqual([2]);
    });
    it("multiple", function () {
        expect(array.range(42,50)).toEqual([42,43,44,45,46,47,48,49,50]);
    });
});

Time
15 minutes
Activity
Small Groups

Arrays Continued

Follow the (second part of the) Sum of a Range Exercise to write a sum function that passes the following tests.

describe("sum", function () {
    it("empty", function () {
        expect(array.sum([])).toBe(0);
    });
    it("single", function () {
        expect(array.sum([2])).toBe(2);
    });
    it("multiple", function () {
        expect(array.sum(array.range(1,10))).toBe(55);
    });    
});

Variadic Functions

Aside
15 minutes
Activity
Demo/Discussion

Traditional JavaScript supports the arguments object, which is something like an array of all the arguments passed to the function.

function makemap (){
    var map={};
    if (arguments.length %2 != 0)
        return map;

    for (var i=0; i<arguments.length; i+=2) {

    }

    return map;

}

ES2015 supports rest arguments similar to those in Racket. These are more general than the arguments object, and generally preferred.

function brag(name,...args){
    console.log(name + " has");
    for (var i=0; i<args.length; i++) {
        console.log("\t"+args[i]);
    }
}

ES2015 also supports default values for function parameters

function win(person,thing="a brick"){
    console.log(person + " won " + thing);
}

Adding step argument to range.

Time
20 minutes
Activity
Small groups

Using the method of your choice, add an optional step argument to the range function so that the following tests pass. The original tests should keep passsing, that's a big part of the point of having unit tests.

    it("step 2", function () {
        expect(array.range(1,10,2)).toEqual([1,3,5,7,9]);
    });        
    it("step -1", function () {
        expect(array.range(5,2,-1)).toEqual([5,4,3,2]);
    });