Skip to content

Instantly share code, notes, and snippets.

@stuarthallows
Last active January 16, 2019 15:51
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stuarthallows/5875239 to your computer and use it in GitHub Desktop.
Save stuarthallows/5875239 to your computer and use it in GitHub Desktop.
Notes from the Pluralsight course, 'Structuring JavaScript Code'.
// 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