Created
February 27, 2016 21:43
-
-
Save balbuf/f172d7570f5c2b4c7ba1 to your computer and use it in GitHub Desktop.
Safe JavaScript typeof checking for a deep property on a variable
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
/** | |
* Pass a defined variable and an arbitrary number of | |
* property names to get the typeof the deepest property. | |
* @param {mixed} value any defined JS variable | |
* optional, unlimited: | |
* @param {string|array} property name or array of args to call the previous property with and use that value | |
* @return {string|false} typeof that property or false if evaluating the chain would result in a reference error | |
* | |
* @example | |
* typeofProp(window,'location','href','toString',[],'substr','foo','bar'); // false | |
* typeofProp(window,'location','href','toString',[],'substr','foo'); // "undefined" | |
* typeofProp(window,'location','href','toString',[],'substr'); // "function" | |
* typeofProp(window,'location','href','toString',[]); // "string" | |
* typeofProp(window,'location','href','toString'); // "function" | |
* typeofProp(window,'location','href'); // "string" | |
* typeofProp(window,'location'); // "object" | |
* typeofProp(window); // "object" | |
* typeofProp(window,'location','href',[]); // false | |
* if (typeofProp(location,'href','substr',[]) && location.href.substr('https:') === 0) { | |
* console.log('HTTPS!'); | |
* } | |
*/ | |
function typeofProp(value) { | |
var propertyChain = Array.prototype.slice.call(arguments, 1), property, next; | |
while (propertyChain.length) { | |
property = propertyChain.shift(); | |
if (Array.isArray(property)) { | |
if (typeof value === 'function') { | |
value = value.apply(this,property); | |
} else { | |
return false; | |
} | |
} else { | |
next = value[ property ]; | |
// if this is a function that will be called, bind it to the current value | |
value = typeof next === 'function' && Array.isArray(propertyChain[0]) ? next.bind(value) : next; | |
} | |
// undefined ain't got no properties! | |
if (propertyChain.length && typeof value === 'undefined') { | |
return false; | |
} | |
} | |
return typeof value; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment