xt
v0.3.3
Published
Lightweight prototype extend library
Readme
_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 === trueassign 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 === Cif 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 === undefinedYou 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 === trueThis 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._eventsBecause 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 obj[propPath] 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
