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
Basic JS (Week 1, Day 3, Segment 2)
By Amal Augustine
Basic JS (Week 1, Day 3, Segment 2)
- 219