Created
September 12, 2012 20:57
-
-
Save influx6/3709875 to your computer and use it in GitHub Desktop.
HasOwnProperty Shim
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
In my heavy search to both understand the underline code and functionality of most | |
of the libraries i am building and managing,the one pure function that seems to have always eluded me was the hasOwnProperty function attributed to all JS objects. | |
I know browser support is widespread and i thank God for that,but am not the | |
type to just use something i don't understand,after a long, | |
mind bending,play testing in the js console to both understand how the prototyping system | |
works,how and why new objects point directly to the prototype,i finally came up with a shim that works 90% of the time even far more better than that located in the Modernizr annotated source code,ya you heard me better. | |
It seems the trick was really on how prototypes and constructors are | |
assigned and also depends on you how deep you wish to go into that tree,since the 'in'(for in loop and others) handle going deep within the prototype | |
and object tree there is not need to try to recreate that,therefore this function searches only one level deep.Anyway to much talk,heres the shim: | |
//written by Alexander Adeniyi Ewetumo | |
hasOwn = function(obj,elem,value){ | |
if(Object.hasOwnProperty){ | |
//return Object.hasOwnProperty.call(obj,elem); | |
} | |
var keys,constroKeys,protoKeys,state = false,fn = function(e,i){ | |
if(value){ | |
state = (e === value) ? true : false; | |
return; | |
} | |
state = true; | |
}; | |
if(!this.isFunction(obj)){ | |
/* when dealing pure instance objects(already instantiated | |
* functions when the new keyword was used,all object literals | |
* we only will be checking the object itself since its points to | |
* its prototype against its constructors.prototype | |
* constroKeys = this.keys(obj.constructor); | |
*/ | |
keys = this.keys(obj); | |
//ensures we are not dealing with same object re-referening,if | |
//so,switch to constructor.constructor call to get real parent | |
protoKeys = this.keys( | |
((obj === obj.constructor.prototype) ? obj.constructor.constructor.prototype : obj.constructor.prototype) | |
); | |
if(this.any(keys,elem,(value ? fn : null)) && !this.any(protoKeys,elem,(value ? fn : null))) | |
return state; | |
} | |
/* when dealing with functions we are only going to be checking the | |
* object itself vs the objects.constructor ,where the | |
* objects.constructor points to its parent if there was any | |
*/ | |
//protoKeys = this.keys(obj.prototype); | |
keys = this.keys(obj); | |
constroKeys = this.keys(obj.constructor); | |
if(this.any(keys,elem,(value ? fn : null)) && !this.any(constroKeys,elem,(value ? fn : null))) | |
return state; | |
}; | |
The any and keys function are custom functions created for my utility belt for my http://github.com/influx6/Stub library. | |
The trick was simple when dealing directly on checking the prototype,to get rather the obj.constructor.constructor.prototype of the prototype | |
to get to the parents prototype or else we endup just getting back the same prototype if its just obj.constructor.prototype,and on the pure function checked, | |
nothing more than check the object itself and its constructor(obj.constructor), | |
now the case of checking an object may be confusing at first seems | |
we checking the object as before in the function case, | |
the real kicker here is that when at a pure function level before it gets instantied with the 'new' keyword,the function points to its own constructor, | |
therefore Function.constructor points to its parent constructor which is | |
that of the Function object, | |
while in the case of prototype or instantiated objects,is that the instantiated function now points to its prototype, | |
therefore the need to use the constructor.constructor.prototype to get to its | |
parent real prototype. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment