Basic ES5

Week 1

Day 3

Objects

An object is a

collection of properties

A property is a
named container for a value
w/ some additional attributes

Definition

The name of a property  is called a key ;
thus, an object  can be considered as
a collection of key-value pairs .

There are similar concepts in other programming languages,
e.g., Map, Dictionary, Associative Array, Symbol Table, Hash Table , ...

  • Property Accessors (Dot and square notations)
  • this in objects
  • Other gotchas when using this.
    • Functions Inside Methods Shadow this
    • Losing this When Extracting a Method
  • Inheritance
    • Javascript inheritance by examples
    • Setting and Deleting Affects Only Own Properties
    • Sharing Data Between Objects via a Prototype
    • Prototypal Chain

Review

Properties

  • all objects in JavaScript are maps (dictionaries) from strings to values.
  • A (key, value) entry in an object is called a property .  The key of a property is always a text string.
  • 3 Kinds of Properties

  • Properties (or named data properties)
  • Accessors (or named accessor properties)
  • Internal properties
    • Exist only in the ECMAScript language specification.

 

Accessing Properties

Dot Notation

var jane = {
  name: 'Jane',

 'desc.func': function () {
      return 'Person named ' + this.name;
  },
};
$ jane.name

// 'jane'
$ jane['desc.func']

// [Function]

Bracket Notation

this in objects

this  refers to the object on which the method has been invoked

> var obj = { method: returnThisStrict };
> obj.method() === obj
true

Normal functions in sloppy mode

function returnThisSloppy() {
    return this
}
> returnThisSloppy() === window
true

Normal functions in strict mode

function returnThisStrict() {
    'use strict';
    return this
}

> returnThisStrict() === undefined
true

Pitfalls

Losing this When Extracting a Method

var counter = {
    count: 0,
    inc: function () {
        this.count++;
    }
}
  • We have called the value of counter.inc  as a function.
  • Hence, this  is the global object and we have performed window.count++ .
  • window.count  does not exist and is undefined . Applying the ++  operator to it sets it to NaN.
  • Use strict mode for avoiding this.
> var func = counter.inc;
> func()
> counter.count  // didn’t work
0

How to properly extract a method

> var func3 = counter.inc.bind(counter);
> func3()
> counter.count  // it worked!
1

Callbacks and extracted methods

function callIt(callback) {
    callback();
}
> callIt(counter.inc)

> callIt(counter.inc.bind(counter))

Pitfall

Functions Inside Methods Shadow this

var obj = {
    name: 'Jane',
    friends: [ 'Tarzan', 'Cheeta' ],
    loop: function () {
        'use strict';
        this.friends.forEach(
            function (friend) {  // (1)
                console.log(this.name+' knows '+friend);  // (2)
            }
        );
    }
};

> obj.loop()

What to do?

Workaround 1: that = this

loop: function () {
    'use strict';
    var that = this;
    this.friends.forEach(function (friend) {
        console.log(that.name+' knows '+friend);
    });
}

Workaround 2: bind()

loop: function () {
    'use strict';
    this.friends.forEach(function (friend) {
        console.log(this.name+' knows '+friend);
    }.bind(this));  // (1)
}

Workaround 3: a thisValue for forEach()

this.friends.forEach(function (friend) {
        console.log(this.name+' knows '+friend);
}, this);
  • Array (as Objects)

  • Array Methods

    • Map

    • Reduce

    • Filter

    • forEach

    • ...

  • mutating and non-mutating methods

Arrays

  • An array is a map from indices (natural numbers, starting at zero) to arbitrary values.
  • The values (the range of the map) are called the array’s elements.
  • The most convenient way of creating an array is via an array literal.
> var arr = [ 'a', 'b', 'c' ]; // array literal
> arr[0]  // get element 0
'a'
> arr[0] = 'x';  // set element 0
> arr
[ 'x', 'b', 'c' ]
  • Arrays Are Maps, Not Tuples
  • The ECMAScript standard specifies arrays as maps (dictionaries) from indices to values.

Arrays Can Also Have Properties

  • Arrays are still objects and can have object properties.
  • Those are not considered part of the actual array; that is, they are not considered array elements.
> var arr = [ 'a', 'b' ];
> arr.foo = 123;
> arr
[ 'a', 'b' ]
> arr.foo
123

The Array Constructor

  • There are two ways to use the constructor Array:
    • you can create an empty array with a given length  
    • an array whose elements are the given values.
> var arr = new Array(2);
> arr.length
2
> arr  // two holes plus trailing comma (ignored!)
[ , ,]

// The same as ['a', 'b', 'c']:
var arr1 = new Array('a', 'b', 'c'); 
// AVOID this.

An empty array with a given length has only holes in it!

The problem is that you can’t create arrays with a single number in them, because that is interpreted as creating an array whose length is the number:

> new Array(2)  // alas, not [ 2 ]
[ , ,]

> new Array(5.7)  // alas, not [ 5.7 ]
RangeError: Invalid array length

> new Array('abc')  // ok
[ 'abc' ]

Array Prototype Methods

Adding and Removing Elements (Destructive)

Array.prototype.shift()

Removes the element at index 0 and returns it. The indices of subsequent elements are decremented by 1:

 

> var arr = [ 'a', 'b' ];

> arr.shift()
'a'
> arr
[ 'b' ]

Array.prototype.unshift(elem1?, elem2?, ...)

Prepends the given elements to the array. It returns the new length:

> var arr = [ 'c', 'd' ];
> arr.unshift('a', 'b')
4
> arr
[ 'a', 'b', 'c', 'd' ]

Array.prototype.pop()

Removes the last element of the array and returns it:

> var arr = [ 'a', 'b' ];
> arr.pop()
'b'
> arr
[ 'a' ]

Array.prototype.push(elem1?, elem2?, ...)

Adds the given elements to the end of the array. It returns the new length

> var arr = [ 'a', 'b' ];
> arr.push('c', 'd')
4
> arr
[ 'a', 'b', 'c', 'd' ]

Sorting and Reversing Elements (Destructive)

Array.prototype.reverse()

Array.prototype.sort(compareFunction?)

> var arr = [ 'a', 'b', 'c' ];
> arr.reverse()
[ 'c', 'b', 'a' ]
> arr // reversing happened in place
[ 'c', 'b', 'a' ]
> var arr = ['banana', 'apple', 'pear', 'orange'];
> arr.sort()
[ 'apple', 'banana', 'orange', 'pear' ]
> arr  // sorting happened in place
[ 'apple', 'banana', 'orange', 'pear' ]

Concatenating, Slicing, Joining (Nondestructive)

Array.prototype.concat(arr1?, arr2?, ...)

Array.prototype.slice(begin?, end?)

Array.prototype.join(separator?)

> var arr = [ 'a', 'b' ];
> arr.concat('c', ['d', 'e'])
[ 'a', 'b', 'c', 'd', 'e' ]

> arr
[ 'a', 'b' ]
> [ 'a', 'b', 'c', 'd' ].slice(1, 3)
[ 'b', 'c' ]
> [3, 4, 5].join('-')
'3-4-5'
> [3, 4, 5].join()
'3,4,5'
> [3, 4, 5].join('')
'345'

> [undefined, null].join('#')
'#'

Searching for Values (Nondestructive)

Array.prototype.indexOf(searchValue, startIndex?)

Array.prototype.lastIndexOf(searchElement, startIndex?)

> [ 3, 1, 17, 1, 4 ].indexOf(1)
1
> [ 3, 1, 17, 1, 4 ].indexOf(1, 2)
3

> [NaN].indexOf(NaN)
-1

> [ 3, 1, 17, 1, 4 ].lastIndexOf(1)
3
> [ 3, 1, 17, 1, 4 ].lastIndexOf(1, -3)
1

Iteration (Nondestructive)

Examination Methods

Array.prototype.forEach(callback, thisValue?)

Array.prototype.every(callback, thisValue?)

Array.prototype.some(callback, thisValue?)

var arr = [ 'apple', 'pear', 'orange' ];
arr.forEach(function (elem) {
    console.log(elem);
});

> function isEven(x) { return x % 2 === 0 }
> [ 2, 4, 6 ].every(isEven)
true
> [ 2, 3, 4 ].every(isEven)
false

> function isEven(x) { return x % 2 === 0 }
> [ 1, 3, 5 ].some(isEven)
false
> [ 1, 2, 3 ].some(isEven)
true

Transformation Methods

Array.prototype.map(callback, thisValue?)

Array.prototype.reduce(callback, initialValue?)

> [ 1, 2, 3 ].map(function (x) { return 2 * x })
[ 2, 4, 6 ]

> [ 1, 0, 3, 0 ].filter(function (x) { return x !== 0 })
[ 1, 3 ]

function add(prev, cur) {
    return prev + cur;
}
console.log([10, 3, -1].reduce(add)); // 12
Made with Slides.com