time-to-botec

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

main.js (3036B)


      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 isObject = require( './../../is-object' );
     24 var isFunction = require( './../../is-function' );
     25 var getPrototypeOf = require( '@stdlib/utils/get-prototype-of' );
     26 var hasOwnProp = require( './../../has-own-property' );
     27 var nativeClass = require( '@stdlib/utils/native-class' );
     28 
     29 
     30 // VARIABLES //
     31 
     32 var objectPrototype = Object.prototype;
     33 
     34 
     35 // FUNCTIONS //
     36 
     37 /**
     38 * Tests that an object only has own properties.
     39 *
     40 * @private
     41 * @param {Object} obj - value to test
     42 * @returns {boolean} boolean indicating if an object only has own properties
     43 */
     44 function ownProps( obj ) {
     45 	var key;
     46 
     47 	// NOTE: possibility of perf boost if key enumeration order is known (see http://stackoverflow.com/questions/18531624/isplainobject-thing).
     48 	for ( key in obj ) {
     49 		if ( !hasOwnProp( obj, key ) ) {
     50 			return false;
     51 		}
     52 	}
     53 	return true;
     54 }
     55 
     56 
     57 // MAIN //
     58 
     59 /**
     60 * Tests if a value is a plain object.
     61 *
     62 * @param {*} value - value to test
     63 * @returns {boolean} boolean indicating whether value is a plain object
     64 *
     65 * @example
     66 * var bool = isPlainObject( {} );
     67 * // returns true
     68 *
     69 * @example
     70 * var bool = isPlainObject( null );
     71 * // returns false
     72 */
     73 function isPlainObject( value ) {
     74 	var proto;
     75 
     76 	// Screen for obvious non-objects...
     77 	if ( !isObject( value ) ) {
     78 		return false;
     79 	}
     80 	// Objects with no prototype (e.g., `Object.create( null )`) are plain...
     81 	proto = getPrototypeOf( value );
     82 	if ( !proto ) {
     83 		return true;
     84 	}
     85 	// Objects having a prototype are plain if and only if they are constructed with a global `Object` function and the prototype points to the prototype of a plain object...
     86 	return (
     87 		// Cannot have own `constructor` property:
     88 		!hasOwnProp( value, 'constructor' ) &&
     89 
     90 		// Prototype `constructor` property must be a function (see also https://bugs.jquery.com/ticket/9897 and http://stackoverflow.com/questions/18531624/isplainobject-thing):
     91 		hasOwnProp( proto, 'constructor' ) &&
     92 		isFunction( proto.constructor ) &&
     93 		nativeClass( proto.constructor ) === '[object Function]' &&
     94 
     95 		// Test for object-specific method:
     96 		hasOwnProp( proto, 'isPrototypeOf' ) &&
     97 		isFunction( proto.isPrototypeOf ) &&
     98 
     99 		(
    100 			// Test if the prototype matches the global `Object` prototype (same realm):
    101 			proto === objectPrototype ||
    102 
    103 			// Test that all properties are own properties (cross-realm; *most* likely a plain object):
    104 			ownProps( value )
    105 		)
    106 	);
    107 }
    108 
    109 
    110 // EXPORTS //
    111 
    112 module.exports = isPlainObject;