Elementry js series - I
Data types
- Boolean
- Null
- Undefined
- Number
- String
- Symbol (new in ECMAScript 6)
- Object
Function declaration
function square(number) {
return number * number;
}
Function expression
var square = function (number) {
return number * number;
};
Iterator
An iterator-object knows how to access items from a collection one at a time. It provides a
next()
method which returns the next item in the sequence. This method returns an object with two properties: done and value.
function arrayIterator(array) {
var nextIndex = 0;
return {
next: function() {
return nextIndex < array.length ? {value: array[nextIndex++], done: false} : {done: true};
}
}
}
var it = makeIterator(['yo', 'ya']);
console.log(it.next().value); // 'yo'
console.log(it.next().value); // 'ya'
console.log(it.next().done); // true
Iterable
An iterable-object must have a property with a
Symbol.iterator
key. Some built-in types i.e.Array
orMap
have a default iteration behavior.
var myIterable = {}
myIterable[Symbol.iterator] = function* () {
yield 1;
yield 2;
yield 3;
};
for(value of myIterable) {
console.log(value);
}
for…in statement
Iterates over all the enumerable properties of an object.
var info = {username: 'Lousy', password: 'NoSmoking!'};
for(var key in info) {
console.log(key);
console.log(info[key]);
}
for…of statement
Iterates over iterable objects i.e.
Array
,Map
,Set
,arguments
,NodeList
etc.
var images = document.querySelectorAll('img');
for(var image of images) {
console.log(image);
}
Object.create
// polyfill
if (typeof Object.create != 'function') {
Object.create = (function(undefined) {
var Temp = function() {};
return function (prototype, propertiesObject) {
if(prototype !== Object(prototype) && prototype !== null) {
throw TypeError('Argument must be an object, or null');
}
Temp.prototype = prototype || {};
if (propertiesObject !== undefined) {
Object.defineProperties(Temp.prototype, propertiesObject);
}
var result = new Temp();
if(prototype === null) {
result.__proto__ = null;
}
Temp.prototype = null;
return result;
};
})();
}
Closure
Normally, the local variables within a function only exist for the duration of that function’s execution. A closure is a special kind of object that combines two things: a function, and the environment in which that function was created.
Below, add5
and add10
are both closures. They share the same function body definition, but store different environments.
function makeAdder(x) {
return function(y) {
return x + y;
};
}
var add5 = makeAdder(5);
var add10 = makeAdder(10);
console.log(add5(2)); // 7
console.log(add10(2)); // 12
Object.defineProperty`
var obj = {};
var bValue = 'Billy';
Object.defineProperty(obj, 'name', {
__proto__: null, // no inherited properties
get: function() { return bValue; },
set: function(newValue) { bValue = newValue; },
// not enumerable
// not configurable
// not writable
// as defaults
});
Extend
var extend = function(isDeep, out) {
out = out || {};
for (var i = 1; i < arguments.length; i++) {
var obj = arguments[i];
if (!obj)
continue;
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
if (typeof obj[key] === 'object' && isDeep)
out[key] = extend(true, out[key], obj[key]);
else
out[key] = obj[key];
}
}
}
return out;
};
extend(true, {}, objA, objB);
Event order
Any event taking place (in W3C
event model) is first captured until it reaches the target element and then bubbles up again. So we can opt to register an event handler in the capturing or in the bubbling phase by passing true
or false
in the last argument of addEventListener()
method respectively.
<div id="parent">
<div id="child"></div>
</div>
Event capturing
When we use event capturing, the event handler of parent
fires first and then the event handler of child
.
Event bubbling
When we use event capturing, the event handler of child
fires first and then the event handler of parent
.
target/srcElement
An event has a target
or srcElement
property that contains a reference to the element the event happened on.
currentTarget
It contains a reference to the element the event is currently being handled by.
Event.preventDefault
Prevents the default action of an event without stopping further propagation of it.
Event.stopPropagation
Prevents further propagation of the current event in the capturing and bubbling phases.
Event.stopImmediatePropagation
If several listeners are attached to the same element for the same event type, they are called in order in which they have been added. If during one such call, event.stopImmediatePropagation()
is called, no remaining listeners will be called.
Event delegation
<ul id="parent-list">
<li id="post-1">Item 1</li>
<li id="post-2">Item 2</li>
<li id="post-3">Item 3</li>
<li id="post-4">Item 4</li>
<li id="post-5">Item 5</li>
<li id="post-6">Item 6</li>
</ul>
document.getElementById("parent-list").addEventListener("click", function(e) {
// e.target is the clicked element!
// If it was a list item
if(e.target && e.target.nodeName == "LI") {
// do something with the li element
}
});
Miscellaneous
var foo = new Function('console.log("Look! that\'s you do it!")');
Object.getPrototypeOf(foo) === Function.prototype; // true
Wierd parts
var a;
a + 3; // NaN
var b = null;
b + 3; // 3
b * 3; // 0