Last active
December 15, 2015 03:09
-
-
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…
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
/* | |
* 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; | |
}; | |
})); |
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
/* | |
* 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