function getOwnPropertyDescriptors( value ) {
	var symbols;
	var names;
	var desc;
	var out;
	var i;

	out = {};

	// Get the value's own enumerable and non-enumerable properties:
	names = propertyNames( value );

	// For each property name, retrieve the property descriptor...
	for ( i = 0; i < names.length; i++ ) {
		desc = propertyDescriptor( value, names[ i ] );
		if ( desc ) {
			// The following is equivalent to `out[ names[i] ] = desc`, but accounts for the possibility of a "poisoned" `Object` prototype (i.e., an `Object.prototype` having a property with a setter which throws).
			defineProperty( out, names[ i ], {
				'configurable': true,
				'enumerable': true,
				'writable': true,
				'value': desc
			});
		}
	}

	// Get the value's symbol properties:
	symbols = propertySymbols( value );

	// For each symbol property, retrieve the property descriptor...
	for ( i = 0; i < symbols.length; i++ ) {
		desc = propertyDescriptor( value, symbols[ i ] );
		if ( desc ) {
			// The following is equivalent to `out[ symbols[i] ] = desc`, but accounts for the possibility of a "poisoned" `Object` prototype (i.e., an `Object.prototype` having a property with a setter which throws).
			defineProperty( out, symbols[ i ], {
				'configurable': true,
				'enumerable': true,
				'writable': true,
				'value': desc
			});
		}
	}

	return out;
}
Returns an object's own property descriptors.

## Notes

-   In contrast to the built-in `Object.getOwnPropertyDescriptors()`, this function returns an empty object if provided `undefined` or `null`, rather than throwing an error.

@private
@param {*} value - input object
@returns {Object} property descriptors

@example
var obj = {
    'beep': 'boop',
    'foo': 3.14
};

var desc = getOwnPropertyDescriptors( obj, 'foo' );
// returns {...}