Last active
January 16, 2019 15:51
-
-
Save stuarthallows/5875239 to your computer and use it in GitHub Desktop.
Notes from the Pluralsight course, 'Structuring JavaScript Code'.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// PROTOTYPE | |
// Modularize code into re-usable objects, take variables and functions out of global namespace, | |
// functions loaded into memory once whereas the state is all held in the objects, can override | |
// functions through prototyping. | |
// Drawbacks: heavy use of 'this' keyword and the constructor is separate from the prototype definition. | |
var Calculator = function(eq) { | |
// Variables defined in constructor and are unique to each instance. | |
this.eqCtl = document.GetElementById(eq); | |
}; | |
Calculator.prototype = { | |
// Methods defined in prototype are shared across instance. | |
add: function (x, y) { | |
var val = x + y; | |
this.eqCtl.innerHTML = val; | |
} | |
} | |
var c = new Calculator(); | |
c.add(2, 2); | |
// Then users can override functionality via prototype. | |
Calculator.prototype.add = function(x, y) { | |
// my implementation. | |
var val = x - y; | |
this.eqCtl.innerHTML = val; | |
} | |
var c = new Calculator(); | |
c.add(2, 2); | |
// PROTOTYPE WITH NAMESPACE | |
var myNS = myNS || {}; | |
myNS.Calculator = function(eq) { | |
// Variables defined in constructor and are unique to each instance. | |
this.eqCtl = document.GetElementById(eq); | |
}; | |
myNS.Calculator.prototype = { | |
'use strict'; | |
// Methods defined in prototype are shared accross instance. | |
add: function (x, y) { | |
var val = x + y; | |
this.eqCtl.innerHTML = val; | |
} | |
} | |
var c = new myNS.Calculator(); | |
c.add(2, 2); | |
// REVLEALING PROTOTYPE | |
var Calculator = function(eq) { | |
// State goes here. | |
this.eqCtl = document.GetElementById(eq); | |
}; | |
Calculator.prototype = function() { | |
// Private memebers. | |
var add = function (x, y) { | |
var val = x + y; | |
this.eqCtl.innerHTML = val; | |
}; | |
return { | |
// Public members. | |
add: add | |
} | |
}(); | |
// In JavaScript this represents the calling context, so when calling from one method to another inside an object in the | |
// called function 'this' represents the calling function not the object, so need to pass this from the caller to the | |
// called method. | |
// As a workaround call the 'call' method to set the context in the caller, thus | |
Calculator.prototype = function() { | |
// Private memebers. | |
var clearNumbers = function (x, y) { | |
setVal('0', this); | |
}, | |
setVal = function(val, thisObj) { | |
thisObj.currentNumberCtl.innerHTML = val; | |
}; | |
return { | |
// Public members. | |
setVal: setVal | |
} | |
}(); | |
// would be rewritten as | |
Calculator.prototype = function() { | |
// Private memebers. | |
var clearNumbers = function (x, y) { | |
setVal.call(this, '0'); | |
}, | |
setVal = function(val) { | |
this.currentNumberCtl.innerHTML = val; | |
}; | |
return { | |
// Public members. | |
setVal: setVal | |
} | |
}(); | |
// EXTENDING WITH THE REVLEALING MODULE PATTERN | |
Calculator.prototype.add = function(x, y) { | |
// Overriding a method. | |
this.innerHTML = x + y * 2; | |
}; | |
Calculator.prototype.square = function(x) { | |
// Extending the object. | |
this.innerHTML = x * x; | |
}; | |
// CLOSURE DEMO 1 | |
// Pattern provides reuse, encapsulation and maintainability. | |
/* an inner function always has access to the vars and parameters of its | |
outer function , even after the outer function has returned. */ | |
function myClosure() { | |
// date object hangs around between calls. | |
var date = new Date(); | |
// nested function | |
return function() { | |
return date.getMilliseconds(); | |
}; | |
} | |
var f = myClosure(); | |
f(); | |
// No new date object created here. | |
f(); | |
// date goes out of scope when f does. | |
// CLOSURE DEMO 2 - MODULE PATTERN | |
var MyClosure2 = function () { | |
var date = new Date(); | |
var myNestedFunc = function() { | |
return date.getMilliseconds(); | |
}; | |
return { | |
foo: myNestedFunc; | |
}; | |
} | |
var f = new MyClosure2(); | |
f.foo(); | |
// MODULE PATTERN WITH NAMESPACE | |
var myNS = myNS || {}; | |
myNS.MyClosure2 = function () { | |
var date = new Date(); | |
var myNestedFunc = function() { | |
return date.getMilliseconds(); | |
}; | |
return { | |
foo: myNestedFunc | |
}; | |
} | |
var f = new myNS.MyClosure2(); | |
f.foo(); | |
// REVEALING MODULE PATTERN | |
var myClosure2 = (function () { | |
'use strict'; | |
var date = new Date(), | |
myNestedFunc = function() { | |
return date.getMilliseconds(); | |
}; | |
return { | |
foo: myNestedFunc | |
}; | |
}()); | |
// As the function is self instantiating the user does not need to use the new keyword, thus the | |
// initial lower case naming. The object becomes a singleton, new instances are not created. | |
myClosure2.foo(); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment