Constructor hacking for modularity
by James Greene
HTML
<h1>Constructor Hacking for Modularity</h1>
JavaScript
/* Core module */
var clients = [];
function ZeroClipboard() {
if (typeof ZeroClipboard.Client === "function") {
var client = ZeroClipboard.Client.apply(this, arguments);
clients.push(client);
return client;
}
}
ZeroClipboard.Core = {
setPendingText: function(text) {
// TODO: Set `text` for Flash
}
};
/* Core and/or other modules that add `ZeroClipboard.prototype.*` methods */
ZeroClipboard.prototype.setText = function(text) {
ZeroClipboard.Core.setPendingText(text);
return this;
};
/* Client module */
// EXTREMELY IMPORTANT
// This instance must be created before the `ZeroClipboard.Client` function is defined
var ZC_ClientProto = new ZeroClipboard();
ZeroClipboard.Client = function (val1, val2) {
// EXTREMELY IMPORTANT
// Enforce that the constructor is called with the `new` operator.
// The guts of the `ZeroClipboard` function will NOT be calling it with the `new` operator.
// This allows the arguments to be determined by the author of `ZeroClipboard.Client`.
if (!(this instanceof ZeroClipboard.Client)) {
return new ZeroClipboard.Client(val1, val2);
}
console.log("instanceof Client? " + (this instanceof ZeroClipboard.Client));
console.log("instanceof ZC? " + (this instanceof ZeroClipboard));
for (var i = 0, len = arguments.length; i < len; i++) {
console.log("arg " + i + " = " + JSON.stringify(arguments[i]));
}
}
// EXTREMELY IMPORTANT
// This will ensure that the `Client` instance gets all of the `ZeroClipboard.prototype.*` methods
ZeroClipboard.Client.prototype = ZC_ClientProto;
// EXTREMELY IMPORTANT
// This will ensure that the `Client` instances understand their inheritance structure
ZeroClipboard.Client.prototype.constructor = ZeroClipboard.Client;
/* Actual usage */
var client = new ZeroClipboard("foo", "bar");
client.setText("blah");