0.3.3 • Published 10 years ago

xt v0.3.3

Weekly downloads
3
License
MIT
Repository
github
Last release
10 years ago

_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