const types = require('../types');
const {isComplex,isObj} = types;
/**
* Get a property descriptor.
*
* This is like `Object.getOwnPropertyDescriptor`, except unlike
* that method, this will travel through the entire prototype chain
* until it finds the descriptor.
*
* @param {object|function} obj - Object to find a property in.
* @param {string} prop - Name of the property we want the descriptor of.
* @param {mixed} [defval] The fallback value if no descriptor is found.
*
* @returns {mixed} The descriptor if found, `defval` if not.
* @alias module:@lumjs/core/obj.getProperty
*/
function getProperty(obj, prop, defval)
{
if (!isComplex(obj)) throw new TypeError("Target must be an object or function");
// Yeah it looks like an infinite loop, but it's not.
while (true)
{
const desc = Object.getOwnPropertyDescriptor(obj, prop);
if (isObj(desc))
{ // Found it.
return desc;
}
// Didn't find it, so let's try the next object in the prototype chain.
obj = Object.getPrototypeOf(obj);
if (!isComplex(obj))
{ // We've gone as far up the prototype chain as we can, bye now!
return defval;
}
}
}
module.exports = getProperty;