extender – Object [ 1222 views ]
Goal: give some additional function to the Object type
available extends:
- objectId: global unique identifier for every DOM and non DOM object
- _bind, _unbind, _trigger: bind logic for every DOM and non DOM object
- _trace, _watch: easy setable trace and watch functionality
- _catch (SET catching): bind a function to the variable setter
- _chain: to investigate the call chains with arguments
The code itself:
(function() { // unique ID
/* usage
read from plain javascript: var id = obj.objectId;
read from jquery: var id = $(this)[0].objectId;
*/
__Object_oIdcnt = 1;
Object.defineProperty(Object.prototype, "__oId", { writable: true });
Object.defineProperty(Object.prototype, "objectId", {
get: function() {
!this.__oId && (this.__oId = __Object_oIdcnt++);
return this.__oId;
}
});
}());
(function() { // _bind, _trigger capability
/* usage
var f = {}; // new Object();
f._bind('evt1.nspc', function(){console.log('first one');});
f._bind('evt2.nspc', function(){console.log('second one');});
f._bind('evt1.nspc2', function(){console.log('third one');});
f._trigger('evt1');
f._trigger('evt2');
f._unbind('.nspc');
f._trigger('evt1');
f._trigger('evt2');
*/
Object.defineProperty(Object.prototype, "__bound", { writable: true });
Object.defineProperty(Object.prototype, "bound", {
get: function() {
this.__bound = this.__bound || [];
return this.__bound;
}
});
TypeExtend(Object, '_bind', function(evt, func) {
var evts = evt.split('.'),
obj = {namespace: (evts[1] && evts[1]), event: evts[0], f:func};
this.bound.push(obj);
return this;
});
TypeExtend(Object, '_unbind', function(evt) {
if(!this.__bound){return false;}
if(!evt){
this.__bound = [];
delete this.__bound;
}
else{
var evts = evt.split('.');
for(var i in this.__bound){
if((evts[1] && this.__bound[i].namespace == evts[1])
|| this.__bound[i].event == evts[0]){
delete this.__bound[i];
}
}
}
this.__bound.shrink(); // drop all undefined items
return this;
});
TypeExtend(Object, '_trigger', function(evt) {
if(!this.__bound){return false;}
for(var i in this.__bound){
if(this.__bound[i].event == evt){
var a = arguments;
this.__bound[i].f && (this.__bound[i].f)(a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[8],a[10]);
}
}
return this;
});
}());
(function() { // _trace, _watch, _catch capability
/* usage
1. simple trace and watch
this._trace('myFunctionName'); ... or ... _trace.call(this, 'myFunctionName');
this._watch('myVariableName'); ... or ... _watch.call(this, 'myVariableName');
2. function bind on variable set
this._catch('myVariableName', function(){...}); ... or ... _catch.call(this, 'myVariableName', function(){...});
*/
var _trace_level = 1;
TypeExtend(Object, '_trace', function(funcName, useChain) {
if(typeof(this[funcName]) != 'function'){_watch.call(this, funcName); return false;}
if(this['__' + funcName]){return false;}
this['__' + funcName] = this[funcName];
this[funcName] = function(){
var a = arguments, _tl = _trace_level;
arguments.callee.caller.toString() && _trace_level++;
var aa = '', aar = [];
for(var ar in a){ a[ar] && aar.push(a[ar].toString()); }
aa = aar.join(',');
if(useChain){
if(_tl < _trace_level){ console.group(funcName + ' (' + aa + ')'); }
else{ console.log(funcName + ' (' + aa + ')'); }
}
else{
console.traceEx('_trace: ' + ' '.repeat(_trace_level) + funcName, 'background: rgba(207, 181, 42, 0.6); color: #000;', arguments);
}
var ret = this['__' + funcName](a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[8],a[10]);
if(_tl < _trace_level){ console.groupEnd(); }
_trace_level = _tl;
return ret;
};
!useChain && console.info('_trace applied to ' + funcName);
return true;
});
_trace = function(fn){ this._trace(fn); };
TypeExtend(Object, '_watch', function(varName, binder) {
if(this['__' + varName]){console.error('unable to apply _watch for ' + varName); return false;}
this['__' + varName] = this[varName];
Object.defineProperty(this, varName, {
get: function() {
!binder && console.traceEx('_watch GET: ' + varName, 'background: rgba(97, 243, 126, 0.6); color: #000;');
return this['__' + varName];
},
set: function(val) {
!binder && console.traceEx('_watch SET: ' + varName + '--> value:' + val, 'background: rgba(243, 151, 151, 0.6); color: #000;');
this['__' + varName] != val && (this._trigger('__set_' + varName, this['__' + varName], val), this['__' + varName] = val);
return this;
}
});
if(binder){ // ezt meg rákötöm figyelésnek
this._bind('__set_' + varName, binder);
console.info('_catch applied to ' + varName);
}
else{
console.info('_watch applied to ' + varName);
}
return true;
});
TypeExtend(Object, '_catch', function(varName, binder) {
return this._watch(varName, binder);
});
_watch = function(vn, binder){ this._watch(vn, binder); };
_catch = function(vn, binder){ this._watch(vn, binder); };
}());
(function() { // _chain
/* usage
1. I have only a simple way to do this
this._chain();
*/
TypeExtend(Object, '_chain', function() {
for(var i in this){
if(typeof this[i] === "function") {
this._trace(i, true);
}
}
console.obj('_chain applied to', this);
});
}());
see also: extend the console, javascript extender (TypeExtend), extender – Array


