Validating existence of object elements
I got tried of writing stuff like
if( app.user == undefined || app.user.address == undefined || app.user.address.zip == undefined){
...
}
So I made a little function to test existence of elements in objects. Originally, I bound it on Object.prototype but I found out the hard way that this is a problem (and later why it's a problem). Instead, it uses a trick from sugar.js to make the function non-enumerable so it doesn't break key-value loops. This means that you have to check if it has already been defined first, because you can't overwrite it once it has been set.
if(Object.prototype.hasProp === undefined){
Object.defineProperty(Object.prototype, 'hasProp', {
value: function() {
var args = Array.prototype.slice.call(arguments);
for( var i=args.length; i-->0; ){
if( typeof args[i] !== "string" ){
throw new TypeError(typeof args[i] + " given in place of string");
}
var period = args[i].indexOf('.');
if(period>-1){
if(!this[args[i].substr(0, period)].hasProp(args[i].substr(period+1))){
return false;
}else{
continue;
}
}
if(this[args[i]]==undefined){
return false;
}
}
return true;
},
enumerable: false
});
}
That means you can do this:
d={a: "bark", b: 0, c: undefined, d: [], e: { a: { b: '1' } }, f: ""};
d.hasProp('a', 'b'); # true
d.hasProp('c'); # false
d.hasProp('e.a'); # true
d.hasProp('e.b'); # false
d.hasProp('e.a.b'); # true
d.hasProp('e.a.c'); # false
d.hasProp('d', 'f'); # true
d.hasProp('a.b'); # false
Note that this is different from hasOwnProperty, since hasOwnProperty is unsafe (can be overwritten) and d.hasOwnProperty('c') === true since d.c exists even though it is undefined.
The original situation is now if( !app.hasProp('user.address.zip')) does the trick. Note: Doesn't work on IE<=8. Should be safe everywhere else.
Minified
void 0===Object.prototype.hasProp&&Object.defineProperty(Object.prototype,"hasProp",{value:function(){for(var a=Array.prototype.slice.call(arguments),b=a.length;0<b--;){if("string"!==typeof a[b])throw new TypeError(typeof a[b]+" given in place of string");var c=a[b].indexOf(".");if(-1<c)if(this[a[b].substr(0,c)].a(a[b].substr(c+1)))continue;else return!1;if(void 0==this[a[b]])return!1}return!0},enumerable:!1});Written by Charles Julian Knight
Related protips
Have a fresh tip? Share with Coderwall community!
JavaScript on a page runs with the privileges of that origin. One altered library, tag manager, or snippet can read inputs, change what people see, and call your APIs as the user.
Security insights from Cside