xt v0.3.3
_xt
Super lightweight prototype extend library
No class or static keywords
No heavy thousands of clones
No heavy magic this.super()
just prototype inheritance
_xt.extend(A, B)
assign to constructor A a new instance of function B as its prototype
(new A) instanceof B === true
_xt.extend(A, B, C)
assign to constructor A a new instance of function B as its prototype
(new A) instanceof B === true
assign to the new instance of B, a singleton instance of C as its prototype and store it in A._xxt
(new A) instanceof C === true
A._xxt instanceof C === true
_xt.extend(A, B, C);
_xt.extend(A2, B2, C);
//the expressions below are true
A2._xxt === A._xxt
A2._xxt.constructor === A._xxt.constructor === C
if B and C set a property object called options, the prototype of A will have the merged options of C into B. We could have called it 'static'.
var A = function(){};
var C = function(){
this.options = {
option1: true,
option2: true
}
_xt.extend(A, function(){
this.options = {
option1: false,
option3: true
}
}, C);
(new A).options =>
{
option1: false,
option2: true,
option3: true
}
new A does not call C as constructor. You have to do it manually, this is also true for instance methods.
var A = function(){
A._xxt.constructor.apply(this, arguments);
};
var C = function(){
this.which = function(){
return C._xxt.method.call(this) + 'c';
};
};
_xt.extend(A, function(){
this.which = function(){
return A._xxt.method.call(this) + 'a';
};
}, C);
(new A).which() === 'ca';
This is not magic as the super() method you can see in other libs
But it's fast.
_xt.extend(A, B, C, D, E)
Like
_xt.extend(A, B, C)
But it mixins in A.prototype the D and E objects or prototypes if D and E are functions.
var D = function(){
this.d = true;
}
_xt.extend(D, function(){
this.beCareful = true;
this.isD = function(){
return true;
}
});
_xt.extend(A, B, C, D);
var a = new A();
//the expressions below are true
a instanceof C
!(a instanceof D)
a.isD()
a.beCareful
a.d === undefined
You probably want a.d to be true but the mixins constructors are not automatically called. We must modify A to call all its mixins constructors.
var A = function(){
_xt.constructMixins(this);
}
(new A).d === true
This works because _xt.mixin stores each mixin in an array (this._mixins). ConstructMixins is useful when you have a deep inheritance with many mixins attached. For more granularity, this works as well:
var A = function(){
D.constructor.call(this);
}
You should be careful when using mixins because the mixin is attached to a prototype potentially used by many others instances. For example, _xt.Notifier is a very simple pubsub constructor which uses an object to store the event handlers.
_xt.Notifier = function(){ this._events = {} };
_xt.extend(A, Pa, null, _xt.Notifier);
_xt.extend(B, Pb, A);
_xt.extend(C, Pc, A);
var a = new A, b = new B, c = new C;
The following is true but you don't want it
a._events === b._events === c._events
Because b.attachEvent('change', bChangeHandler) attach the handler to the change event of a, b and c
a.fireEvent('change') will execute bChangeHandler which is probably not the right behavior
You must think if the constructors should or should not be called.
_xt.mixin(A, B, C, ..)
Equivalent to
_xt.extend(A, Pa, null, B, C, ...)
See the doc above
_xt.constructMixins(obj)
Call the constructor of each mixin attached to obj passing obj as 'this'. The mixins are stored in obj._mixins.
_xt.merge(obj, obj2, obj3, ...)
Assign all the enumerable properties of obj2, obj3, ... to obj. The replacement is from right to left. It is not a clone.
obj1.x = 1;
obj2.x = 2;
obj3.x = 3;
obj3.prop = { merged: false };
_xt.merge(obj1, obj2, obj3);
obj1.prop.merged = false;
//expressions below are true
obj1.x === 3;
obj3.prop === obj1.prop;
obj3.merged = false;
_xt.mergeProp(obj, propPath, propValue)
Merge a path ('prop1.subProp1.subProp2') in obj and set the propValue so that obj.prop1.subProp1.subProp2 === propValue If propValue and objpropPath are both objects, they are merged with _xt.merge, else the value is replaced or created.
_xt.append(obj, obj2, obj3, ...)
Equivalent to _xt.merge(obj, obj2, obj3, ...) but don't replace props if they already exist.
_xt.spliceArgs(args, i, j, obj)
Equivalent to Array.prototype.splice, but for an 'arguments' object
_xt.Notifier
this.attachEvent(name, handler)
Attach to the event called 'name' the handler 'handler'
this.attachEvents(obj)
Attach each event in obj
this.fireEvent(name)
Fire the event called 'name'
this.detachEvent(name, handler)
if handler, remove the handler to the event called 'name' otherwise, remove the event