UNPKG

objects-mixing

Version:

This module is for mixing an objects in one super object.It uses __proto__ property to combine objects, but not just copying properties and methods.

96 lines (88 loc) 4.49 kB
function isValSet(varToCheck) { return typeof(varToCheck) !== "undefined" && varToCheck !== null ; } function typeOfVar(varToCheck) { return {}.toString.call(varToCheck); } function checkArg(arg, numOfVals) { var retArr = []; for(var argInd=0;argInd<arg.length;argInd++) {retArr[argInd] = arg[argInd];} if ( typeOfVar(retArr) !== "[object Array]") { return new Error("Wrong type of the first argument"); } if ( retArr.length < numOfVals ) { return new Error("Wrong number of the functions into array"); } return retArr; } function getConstr(constrDescr) { constructorPri = constrDescr[0]; return typeof constructorPri !== "function" ? new Error("One of the argument is not a function") : constructorPri; } function getArgs(constrDescr) { return ( ( typeOfVar(constrDescr[1]) !== "[object Array]" ) || ( constrDescr[1].length = 1 ) ) ? ( typeOfVar(constrDescr[1]) !== "[object Array]" ? ([constrDescr[1]]):(constrDescr[1]) ) : ( constrDescr[1] ) ; } function getThis(constrDescr) { return ( typeof(constrDescr[2]) === "object" && isValSet(constrDescr[2]) ? ( constrDescr[2] ) : ( undefined ) ); } function splitObjectConstructors() { var objConstructors, firstConstrDescr, nextConstrDescr, constructorPri, argumentsPri, constructorSl, argumentsSl, valOfThis, valOfThisSl; function retObjConstructor(constr, argumentsToConstr, valOfThis) { return constr.apply( isValSet(valOfThis) ? valOfThis : this, argumentsToConstr); } //check arguments if ( (objConstructors = checkArg(arguments,2)) instanceof Error ) throw objConstructors; //if it is not function-constructor, but it is already object objPri = ( typeof(objConstructors[0]) === "object" && typeOfVar(objConstructors[0]) !== "[object Array]" ) && ( isValSet(objConstructors[0]) ) ? objConstructors[0] : function(){ //create first object //try to get first function-constructor and it's properties if ( (firstConstrDescr = checkArg(objConstructors[0],1)) instanceof Error ) throw firstConstrDescr; if ((constructorPri = getConstr(firstConstrDescr)) instanceof Error) throw constructorPri; if ((argumentsPri = getArgs(firstConstrDescr)) instanceof Error) throw argumentsPri; if (( valOfThis = getThis(firstConstrDescr)) instanceof Error) throw argumentsPri; retObjConstructor.prototype = constructorPri.prototype; return new retObjConstructor(constructorPri, argumentsPri, valOfThis); }.call(); //for each object or function-constructor desription objConstructors.forEach( function(objConstructorDescr, index, array){ if ( index == 0 ) return; //if it is not function-constructor, but it is already object ; objSl = ( typeof(objConstructorDescr) === "object" && typeOfVar(objConstructorDescr) !== "[object Array]" ) && ( isValSet(objConstructorDescr) ) ? objConstructorDescr : function() { //create next object //try to get next function-constructor and it's properties if ( (nextConstrDescr = checkArg(objConstructorDescr,1)) instanceof Error ) throw(nextConstrDescr); if ((constructorSl = getConstr(nextConstrDescr)) instanceof Error) throw (constructorSl); if ((argumentsSl = getArgs(nextConstrDescr)) instanceof Error) throw argumentsSl; if (( valOfThisSl = getThis(nextConstrDescr)) instanceof Error) throw argumentsPri; retObjConstructor.prototype = constructorSl.prototype; return new retObjConstructor(constructorSl, argumentsSl, valOfThisSl); }.call(); //find prototype of the first object equal to Object var objMixin = objPri; while( true ) { if ( objMixin.__proto__.hasOwnProperty("constructor") && objMixin.__proto__.constructor == Object ) {break;} else { objMixin = objMixin.__proto__;}; } //change prototype that is equal to Object instance into first object prototypes chain to the next object objMixin.__proto__ = objSl; } ); return objPri; } function addMixinObject(obj) { splitObjectConstructors(this, obj); } Object.prototype.addMixin = addMixinObject; module.exports = exports = splitObjectConstructors;