Object-Oriented JavaScript Notes
https://www.udacity.com/course/viewer#!/c-ud015
This document summarizes content and augments some screenshots for reference.
Lexical Scoping in JavaScript:
Execution Contexts ('in-memory scopes') in JavaScript:
Passing a reference to 'this' with .call()
'extend()' vs. 'Object.create()'
Prototypical Class Definitions
Pseudoclassical Class Definitions
Superclass and Subclass Definitions (Functional Class stye)
Superclass and Subclass Definitions (Pseudoclassical Class style)
Bonus (advanced) example of closures
Code examples with extra comments from the course: https://github.com/batmanimal/object-oriented-js
The global scope is shared between (.js) files.
Either pass in an object and invoke the function or override by using .call() to literally pass in the reference you want to use for this
extend() | is an example function that copies all properties one-time |
Object.create() | creates an ongoing lookup to the parent object |
Note: extend() doesn't exist in vanilla JS. Many libraries include this functionality because it's so useful (jQuery for instance, http://api.jquery.com/jquery.extend).
Here is the code for inherit if you want to copy it:
// pseudoclassical inheritance
// subClass will inherit from superClass
inherit = function(subClass,superClass) {
subClass.prototype = Object.create(superClass.prototype); // delegate to prototype
subClass.prototype.constructor = subClass; // set constructor on prototype
}
inherit(Van,Car);
As further guidance, you can find more elaborate schemes for making pseudoclassical inheritance in JavaScript 'easier'. A Google search offers up this link:
http://phrogz.net/js/classes/OOPinJS2.html
which would allow you to write something like this if you follow the example:
Van.inheritsFrom( Car );
Regarding the fooVar example above, we might ask: is fooVar frozen in time? That is, if fooVar were changed and accessed in a later call of bar(), would fooVar hold the original value or would it have the new value because fooVar is an ongoing lookup? The answer is that it will change because the lookup is ongoing. We can test this in the console of a browser with the use of setTimeout, printing the time and nesting some scopes in an extended version of the fooVar example above. Don’t worry if you don’t understand this, but if you’re curious, this will show you that the variables (eg. fooVar) in the execution context remain 'live', ie. they can be modified and will affect any scopes that have them in their closures. The intended way to understand this is to read the output first and then see what the code was doing to produce it, matching the printed statements to the code.
// zero padding by profitehlolz found on stack overflow:
// http://stackoverflow.com/questions/1267283/how-can-i-create-a-zerofilled-value-using-javascript
function zeropad(n, p, c) {
var pad_char = typeof c !== 'undefined' ? c : '0';
var pad = new Array(1 + p).join(pad_char);
return (pad + n).slice(-pad.length);
}
function getTime(currentdate) {
return currentdate.getHours() + ':'
+ zeropad(currentdate.getMinutes(),2) + ':'
+ zeropad(currentdate.getSeconds(),2);
}
console.log('TEST ' + getTime(new Date()));
var globalVar = 'globalVar ' + getTime(new Date());
function foo() {
var fooVar = 'Foo Variable!', fooDate = new Date();
console.log('Time in foo = ' + getTime(fooDate));
function modGlobalVar() {
globalVar = 'globalVar ' + getTime(new Date());
}
function bar() {
console.log('----------');
console.log('Time in bar = ' + getTime(fooDate));
console.log('fooVar in bar = ' + fooVar); // fooVar is available here
console.log('globalVar in bar = ' + globalVar);
console.log('==========');
}
bar();
console.log('\nThis test shows that fooVar can be changed after bar is defined and run.\n');
fooVar = 'Foo Variable has been changed!';
setTimeout(modGlobalVar, 2500); // modify globalVar before bar is called again
setTimeout(bar, 5000);
}
foo();
Which produces this output (in Chrome’s JavaScript console):
TEST 10:48:04
Time in foo = 10:48:04
----------
Time in bar = 10:48:04
fooVar in bar = Foo Variable!
globalVar in bar = globalVar 10:48:04
==========
This test shows that fooVar can be changed after bar is defined and run.
----------
Time in bar = 10:48:04
fooVar in bar = Foo Variable has been changed!
globalVar in bar = globalVar 10:48:07
==========