I am not an expert with classes and objects and I would like to understand this structure from Brian Kirchoff (see the attached text file coming from the site niceEditor )
Code:
var bkExtend = function(){
var args = arguments;
if (args.length == 1) args = [this, args[0]];
for (var prop in args[1]) args[0][prop] = args[1][prop];
return args[0];
};
function bkClass() { };// One empty class
bkClass.prototype.construct = function() {};// With one empty function construc
bkClass.extend = function(def) {
var classDef = function() {
if (arguments[0] !== bkClass) { return this.construct.apply(this, arguments); }
};
var proto = new this(bkClass);
bkExtend(proto,def);
classDef.prototype = proto;
classDef.extend = this.extend;
return classDef;
};
Then bkClass.extend is used along the script to build the Editor...
var bkExtend = function(){
var args = arguments;
if (args.length == 1) args = [this, args[0]];
for (var prop in args[1]) args[0][prop] = args[1][prop];
return args[0];
};
This chunk clearly wasn't written for readability, since the author didn't name the arguments, nor comment anything, but it seems to be a mix-in function.
Here's a more readable and easier to understand version:
PHP Code:
// This function should probably be called "mixIn"
function bkExtend(receivingObject, propertiesToMixIn) {
// This function can also be called with just one argument -- the properties to mix in
// In that case, the receiving object will be "this"
if (arguments.length == 1) {
propertiesToMixIn = arguments[0];
receivingObject = this;
}
// Copy the properties
for (var propertyName in propertiesToMixIn) {
receivingObject[propertyName] = propertiesToMixIn[propertyName];
}
// Return the receiving object
// This would let us chain method calls
return receivingObject;
}
I'll be back to explain the rest later, if someone else doesn't beat me to it. I have to take care of some 9-to-5 stuff first.
// This function is going to be the base class
// Using the term "class" loosely
function bkClass() {
}
// "extend" is a static method to create a subclass that will inherit from this class
// You can optionally pass in an object of properties that you want to mix in to the new subclass's prototype
bkClass.extend = function (propertiesToMixIn) {
// I renamed the variable "classDef" to "sublcass"
// I think this makes its purpose more clear
var subclass = function () {
// This is an unusual test
// The author is using the first argument to the constructor
// As a way to distinguish between normal instantiation
// Versus instantiation for establishing inheritance
// The more common way to estabish inheritance is by using Crockford's Object.create
// http://javascript.crockford.com/prototypal.html
// Which would eliminate the need for this test
if (arguments[0] !== bkClass) {
// Arguments to the constructor function are passed verbatim to the method named "construct"
return this.construct.apply(this, arguments);
}
};
// This establishes inheritance by creating a new instance of the class we're extending
// The argument "bkClass" prevents the "construct" method from being invoked
// So what we get is a blank object that inherits from the superclass's prototype
var proto = new this(bkClass);
// This is more straightforward when the functions and variables are named appropriatly
// The properties to mix in are copied into what will be the subclass's prototype
bkExtend(proto, propertiesToMixIn);
// The "proto" object, which inherits from the superclass's prototype
// And has all our desired properties mixed in
// Is now the subclass's prototype
subclass.prototype = proto;
// Copy the static "extend" method onto the subclass, so we can extend the subclass
subclass.extend = this.extend;
return subclass;
};
// If any subclass doesn't define a "construct" method, then they will inherit this one
// Which doesn't do anything except to ensure that the "construct" property will be non-null
bkClass.prototype.construct = function () {
};
Bookmarks