time-to-botec

Benchmark sampling in different programming languages
Log | Files | Refs | README

main.js (3182B)


      1 /**
      2 * @license Apache-2.0
      3 *
      4 * Copyright (c) 2018 The Stdlib Authors.
      5 *
      6 * Licensed under the Apache License, Version 2.0 (the "License");
      7 * you may not use this file except in compliance with the License.
      8 * You may obtain a copy of the License at
      9 *
     10 *    http://www.apache.org/licenses/LICENSE-2.0
     11 *
     12 * Unless required by applicable law or agreed to in writing, software
     13 * distributed under the License is distributed on an "AS IS" BASIS,
     14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     15 * See the License for the specific language governing permissions and
     16 * limitations under the License.
     17 */
     18 
     19 'use strict';
     20 
     21 // MODULES //
     22 
     23 var getOwnPropertyDescriptors = require( './../../property-descriptors' );
     24 var getOwnPropertySymbols = require( './../../property-symbols' );
     25 var getPrototypeOf = require( './../../get-prototype-of' );
     26 var objectKeys = require( './../../keys' );
     27 var defineProperty = require( './../../define-property' );
     28 var hasOwnProp = require( '@stdlib/assert/has-own-property' );
     29 
     30 
     31 // MAIN //
     32 
     33 /**
     34 * Returns an object's own and inherited property descriptors.
     35 *
     36 * ## Notes
     37 *
     38 * -   In contrast to the built-in `Object.getOwnPropertyDescriptors()`, this function returns an empty object if provided `undefined` or `null`, rather than throwing an error.
     39 *
     40 * @param {*} value - input object
     41 * @returns {Object} own and inherited property descriptors
     42 *
     43 * @example
     44 * var obj = {
     45 *     'beep': 'boop',
     46 *     'foo': 3.14
     47 * };
     48 *
     49 * var desc = propertyDescriptorsIn( obj );
     50 * // returns { 'beep': {...}, 'foo': {...}, ... }
     51 */
     52 function propertyDescriptorsIn( value ) {
     53 	var desc;
     54 	var keys;
     55 	var obj;
     56 	var tmp;
     57 	var i;
     58 
     59 	if ( value === null || value === void 0 ) {
     60 		return {};
     61 	}
     62 	// Cast the value to an object:
     63 	obj = Object( value );
     64 
     65 	// Walk the prototype chain collecting all property descriptors...
     66 	desc = {};
     67 	do {
     68 		tmp = getOwnPropertyDescriptors( obj );
     69 		keys = objectKeys( tmp );
     70 		for ( i = 0; i < keys.length; i++ ) {
     71 			// The first encountered property descriptor for a property name always takes precedence...
     72 			if ( !hasOwnProp( desc, keys[ i ] ) ) {
     73 				// The following is equivalent to `desc[ keys[i] ] = {...}`, but accounts for the possibility of a "poisoned" `Object` prototype (i.e., an `Object.prototype` having a property with a setter which throws).
     74 				defineProperty( desc, keys[ i ], {
     75 					'configurable': true,
     76 					'enumerable': true,
     77 					'writable': true,
     78 					'value': tmp[ keys[ i ] ]
     79 				});
     80 			}
     81 		}
     82 		keys = getOwnPropertySymbols( tmp );
     83 		for ( i = 0; i < keys.length; i++ ) {
     84 			// The first encountered property descriptor for a symbol property always takes precedence...
     85 			if ( !hasOwnProp( desc, keys[ i ] ) ) {
     86 				// The following is equivalent to `desc[ keys[i] ] = {...}`, but accounts for the possibility of a "poisoned" `Object` prototype (i.e., an `Object.prototype` having a property with a setter which throws).
     87 				defineProperty( desc, keys[ i ], {
     88 					'configurable': true,
     89 					'enumerable': true,
     90 					'writable': true,
     91 					'value': tmp[ keys[ i ] ]
     92 				});
     93 			}
     94 		}
     95 		obj = getPrototypeOf( obj );
     96 	} while ( obj );
     97 
     98 	return desc;
     99 }
    100 
    101 
    102 // EXPORTS //
    103 
    104 module.exports = propertyDescriptorsIn;