|
function log(result) { |
|
var li; |
|
if (typeof(resultsList) === "undefined") { |
|
console.log(result); |
|
} else { |
|
li = document.createElement("li"); |
|
li.textContent = result; |
|
resultsList.appendChild(li); |
|
} |
|
} |
|
|
|
log("Different ways of using a mixin to create property getter functions for model objects ..."); |
|
log("The model object properties are encapsulated and only accessible via the getter functions."); |
|
log("See mixin.js for implementation details."); |
|
|
|
// ************************************************ |
|
// |
|
// Standard getter method accessing variables in closure (no use of mixin). |
|
// |
|
function Model1(options) { |
|
var myOptions = options; |
|
this.get = function(prop) { |
|
return myOptions[prop]; |
|
}; |
|
} |
|
|
|
log("----"); |
|
log("Standard getter method accessing variables in closure (no use of mixin)."); |
|
log("m1 = new Model1({ a:1, b:3, c:3 });"); |
|
log("a = m1.get('a'));"); |
|
|
|
m1 = new Model1({ a:1, b:3, c:3 }); |
|
log("a = " + m1.get("a")); |
|
|
|
// ************************************************ |
|
// |
|
// Standard getter mixin accessing variables saved as properties in Model object |
|
// |
|
// See: section 4. Adding Caching |
|
// http://javascriptweblog.wordpress.com/2011/05/31/a-fresh-look-at-javascript-mixins/ |
|
// |
|
// |
|
var addMixin2 = (function() { |
|
function get(prop) { |
|
return this.options[prop]; |
|
} |
|
return function() { |
|
this.get = get; |
|
return this; |
|
}; |
|
})(); |
|
|
|
function Model2(options) { |
|
addMixin2.call(Model2.prototype); |
|
this.options = options; |
|
} |
|
|
|
log("----"); |
|
log("Standard getter mixin addMixin2() accessing variables saved as properties in Model object."); |
|
log("m2 = new Model2({ a:4, b:5, c:6 });"); |
|
log("a = m2.get('a'));"); |
|
|
|
m2 = new Model2({ a:4, b:5, c:6 }); |
|
log("=> " + m2.get("a")); |
|
|
|
|
|
// ************************************************ |
|
// |
|
// Getter mixin accessing closure variables with the help of function in Model object |
|
// |
|
var addMixin3 = (function() { |
|
function get(prop) { |
|
return this.getPrivate()[prop]; |
|
} |
|
return function() { |
|
this.get = get; |
|
return this; |
|
}; |
|
})(); |
|
|
|
function Model3(options) { |
|
addMixin3.call(Model3.prototype); |
|
var myOptions = options; |
|
this.getPrivate = function() { |
|
return myOptions; |
|
}; |
|
} |
|
|
|
log("----"); |
|
log("Getter mixin addMixin3() accessing closure variables with the help of function in Model object."); |
|
log("m3 = new Model3({ a:7, b:8, c:9 });"); |
|
log("a = m3.get('a'));"); |
|
|
|
m3 = new Model3({ a:7, b:8, c:9 }); |
|
log("=> " + m3.get("a")); |
|
|
|
var Model3a = function(options) { |
|
addMixin3.call(Model3a.prototype); |
|
var myOptions = options; |
|
this.getPrivate = function() { |
|
return myOptions; |
|
}; |
|
}; |
|
|
|
log("Make a second model object with different initial variables."); |
|
log("m3a = new Model3({ a:1, b:3, c:3 });"); |
|
log("a = m3a.get('a'));"); |
|
|
|
m3a = new Model3({ a:1, b:3, c:3 }); |
|
log("=> " + m3a.get("a")); |
|
|
|
// ************************************************ |
|
// |
|
// Mixin accessing it's own closure variables |
|
// |
|
// 'count' is scoped to the function mixed in to the model object |
|
// 'total' is scoped to the mixin itself |
|
// |
|
var addMixin4 = (function() { |
|
var total = 0; |
|
function counter(num) { |
|
var count = num; |
|
return function() { |
|
total++; |
|
return count++; |
|
}; |
|
} |
|
function totalCount() { |
|
return function() { |
|
return total; |
|
}; |
|
} |
|
return function(num) { |
|
this.counter = counter(num); |
|
this.totalCount = totalCount(); |
|
return this; |
|
}; |
|
})(); |
|
|
|
function Model4(num) { |
|
addMixin4.call(Model4.prototype, num); |
|
} |
|
|
|
var Model4a = function(num) { |
|
addMixin4.call(Model4a.prototype, num); |
|
}; |
|
|
|
log("----"); |
|
log("Mixin accessing it's own closure variables that keeps track of both how many "); |
|
log("times the mixin is called from each created function and also the total number"); |
|
log("times the mixin has been called from all functions that use it."); |
|
log("In this case two different Model creation functions are created, Model4()"); |
|
log("and Model4A() and each of them are extended with the same mixin: addMixin4()."); |
|
|
|
log("m4 = new Model4(23);"); |
|
log("m4a = new Model4a(17);"); |
|
|
|
m4 = new Model4(23); |
|
m4a = new Model4a(17); |
|
|
|
log("function call counter tests ..."); |
|
log("m4 function counter starting at 23 ..."); |
|
log("m4.counter(); => " + m4.counter()); |
|
log("m4.counter(); => " + m4.counter()); |
|
log("m4.counter(); => " + m4.counter()); |
|
log("m4.counter(); => " + m4.counter()); |
|
log("total count by all uses of mixin: " + m4.totalCount()); |
|
|
|
log("m4a counter starting at 17 ..."); |
|
log("m4a.counter(); => " + m4a.counter()); |
|
log("m4a.counter(); => " + m4a.counter()); |
|
log("m4a.counter(); => " + m4a.counter()); |
|
log("total count by all uses of mixin addMixin4(): " + m4.totalCount()); |