javascript property extractor optimisation This is a very simple nested property extractor. I wonder if it can be optimised further?

/**
 * Extract nested property from object. If nested property cannot be reached, return value of rescue
 * @param obj Object
 * @param path Can be dot-separated  string or array
 * @param rescue (optional) default value. Defaults to null
 */
function extract(obj, path, rescue){

    if (typeof obj === "object" &amp;&amp; path){

        var elements = typeof path === "string" ? path.split(".") : path;

        if (typeof elements.shift === "function"){

             var head = elements.shift();

             if (obj.hasOwnProperty(head)){

                return (elements.length === 0) ? obj[head] : extract(obj[head], elements, rescue);

             } // if

         } // if

    } // if

    return rescue || null;    

} // extract


var noob = {k1 : {k11 : {k111 : "v1"}}, k2 : { k21 : "v2"}};

console.log(extract(noob, 'k1.k11')); // {k111 : "v1"}
console.log(extract(noob, 'k1.k11.k111')); // v1
console.log(extract(noob, ['k1', 'k11', 'k111'])); // v1
console.log(extract(noob, 'k1.k11.kx')); // null
console.log(extract(noob, 'k2')); //  k2 : { k21 : "v2"}
console.log(extract(noob, 'k2.k21.k22')); // null
console.log(extract(noob, 'k1.k11.k22', "ZUT")); // ZUT     
console.log(extract(noob, '', "ZUT"));  // ZUT          
console.log(extract(false, '', "ZUT"));  // ZUT   


​
Here are some of my thoughts:


I don't see the point in providing the path as a dot separated string, but it may be useful in your application. 
If you keep the dot separated string, then you should consider extracting the recursive function into a separate internal function, so that you don't have to repeat the check of the path argument in each iteration. 
Why do you check for the shift method? If it doesn't exist, then your function will fail silently. The regular "method does not exist" exception would be much more useful. Instead implement the method on the Array.prototype yourself separately if it doesn't exist. 
Finally I would move the path.length == 0 to the start of the function. That is where the break condition of recursive functions are usually expected.