Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@Ragnarokkr
Last active December 15, 2015 03:09
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Ragnarokkr/5192321 to your computer and use it in GitHub Desktop.
Save Ragnarokkr/5192321 to your computer and use it in GitHub Desktop.
Verifying a valid object property could be overly painful when we have to do with 'object.foo.bar.baz.one.two.three'. The goal of these solutions is to give a powerful hand in checking those kind of very-depth-objects. They allow to check for a valid "object path" of any depth. Short-circuiting and caching are provided to speed the check up. Fur…
/*
* Checks object paths of any depth, with short-circuiting and caching.
* Prototype version.
*
* @author Marco Trulla <marco@marcotrulla.it> http://marcotrulla.it
* @version 0.1
* @license MIT http://opensource.org/licenses/MIT
* @return boolean
* @example
*
* var object = { foo: { bar: { baz: 'hello world!' } },
* result;
*
* result = object.isSafePath(); // --> true
* result = object.isSafePath( 'foo.bar.baz' ); // --> true
* result = object.isSafePath( [ 'foo', 'bar', 'baz' ] ) --> true
* result = object.isSafePath( [ 'baz', 'foo', 'bar' ] ) --> false
*/
;(function(root, factory, undefined){
var Object = root.Object;
try {
// We take care to not do a mess with `Object`.
// If the method doesn't exists, an exception is thrown and
// the it will be added.
Object.isSafePath();
} catch (e) {
// This will automatically makes the new method available to all
// the other objects.
Object.prototype.isSafePath = factory();
}
}( window, function(){
return function ( properties ){
var path = [],
root = this,
prop;
if ( typeof properties === 'string' ) {
// if a string such as 'foo.bar.baz' is passed,
// first we convert it into an array of property names
path = properties ? properties.split('.') : [];
} else {
if ( Object.prototype.toString.call( properties ) === '[object Array]' ) {
// if an array is passed, we don't need to do anything but
// to assign it to the internal array
path = properties;
} else {
if ( properties ) {
// any other type not null or undefined will returns false
return false;
}
}
}
// if the path is valid or empty we return with true (because the
// root object is itself a valid path); otherwise false is returned.
while ( prop = path.shift() ) {
// UPDATE: before it was used the if..else statement only, but
// it could to generate an exception if a inexistent object
// member was found. Now it's fixed using a try..catch statement.
// Thanks to xecute (http://stackoverflow.com/users/958632/xecute)
// for the contribution.
try {
if ( prop in root ) {
root = root[prop];
} else {
return false;
}
} catch(e) {
return false;
}
}
return true;
};
}));
/*
* Checks object paths of any depth, with short-circuiting and caching.
* Standalone functional version.
*
* @author Marco Trulla <marco@marcotrulla.it> http://marcotrulla.it
* @version 0.1
* @license MIT http://opensource.org/licenses/MIT
* @return boolean
* @example
*
* var object = { foo: { bar: { baz: 'hello world!' } },
* result;
*
* result = safeObjectPath( object ); // --> true
* result = safeObjectPath( object, 'foo.bar.baz' ); // --> true
* result = safeObjectPath( object, [ 'foo', 'bar', 'baz' ] ) --> true
* result = safeObjectPath( object, [ 'baz', 'foo', 'bar' ] ) --> false
*/
var safeObjectPath = function safeObjectPath( object, properties ) {
var path = [],
root = object,
prop;
if ( !root ) {
// if the root object is null we immediately returns
return false;
}
if ( typeof properties === 'string' ) {
// if a string such as 'foo.bar.baz' is passed,
// first we convert it into an array of property names
path = properties ? properties.split('.') : [];
} else {
if ( Object.prototype.toString.call( properties ) === '[object Array]' ) {
// if an array is passed, we don't need to do anything but
// to assign it to the internal array
path = properties;
} else {
if ( properties ) {
// any other type not null or undefined will returns false
return false;
}
}
}
// if the path is valid or empty we return with true (because the
// root object is itself a valid path); otherwise false is returned.
while ( prop = path.shift() ) {
// UPDATE: before it was used the if..else statement only, but
// it could to generate an exception if a inexistent object
// member was found. Now it's fixed using a try..catch statement.
// Thanks to xecute (http://stackoverflow.com/users/958632/xecute)
// for the contribution.
try {
if ( prop in root ) {
root = root[prop];
} else {
return false;
}
} catch(e) {
return false;
}
}
return true;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment