Deep object select with fallback

A safe way to select a property from an object at any depth, with a fallback value.

by soulwire

JavaScript

var themeA = { name: 'Theme A', caption: { color: 'red' } };
var themeB = { name: 'Theme B', caption: { color: 'green' } };
var themeC = { name: 'Theme C', color: 'blue', caption: { } };
var themeD = { name: 'Theme D' };

function select( target, options, fallback ) {
    
    if ( typeof options === 'string' ) {
        options = [ options ];
    }
    
    function search( prop ) {
        
        var path = prop.split('.'), obj = target;
        
        for ( var i = 0; i < path.length - 1; i++ ) {

            obj = obj[ path[i] ];
            
            if ( !obj ) return false;
        }
        
        return obj[ path[i] ];
    }
    
    for ( var i = 0; i < options.length; i++ ) {
        
        var value = search( options[i] );
        
        if ( value ) return value;
    }
    
    return fallback || null;
}

// Test
var a = select( themeA, ['caption.color', 'color'], 'default' );
var b = select( themeB, ['caption.color', 'color'], 'default' );
var c = select( themeC, ['caption.color', 'color'], 'default' );
var d = select( themeD, ['caption.color', 'color'], 'default' );
var e = select( themeD, 'caption.color' );

console.log( a, b, c, d, e ); // red, green, blue, default, null