index.js
  1  /**
  2   * lodash (Custom Build) <https://lodash.com/>
  3   * Build: `lodash modularize exports="npm" -o ./`
  4   * Copyright jQuery Foundation and other contributors <https://jquery.org/>
  5   * Released under MIT license <https://lodash.com/license>
  6   * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
  7   * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
  8   */
  9  
 10  /** `Object#toString` result references. */
 11  var objectTag = '[object Object]';
 12  
 13  /**
 14   * Checks if `value` is a host object in IE < 9.
 15   *
 16   * @private
 17   * @param {*} value The value to check.
 18   * @returns {boolean} Returns `true` if `value` is a host object, else `false`.
 19   */
 20  function isHostObject(value) {
 21    // Many host objects are `Object` objects that can coerce to strings
 22    // despite having improperly defined `toString` methods.
 23    var result = false;
 24    if (value != null && typeof value.toString != 'function') {
 25      try {
 26        result = !!(value + '');
 27      } catch (e) {}
 28    }
 29    return result;
 30  }
 31  
 32  /**
 33   * Creates a unary function that invokes `func` with its argument transformed.
 34   *
 35   * @private
 36   * @param {Function} func The function to wrap.
 37   * @param {Function} transform The argument transform.
 38   * @returns {Function} Returns the new function.
 39   */
 40  function overArg(func, transform) {
 41    return function(arg) {
 42      return func(transform(arg));
 43    };
 44  }
 45  
 46  /** Used for built-in method references. */
 47  var funcProto = Function.prototype,
 48      objectProto = Object.prototype;
 49  
 50  /** Used to resolve the decompiled source of functions. */
 51  var funcToString = funcProto.toString;
 52  
 53  /** Used to check objects for own properties. */
 54  var hasOwnProperty = objectProto.hasOwnProperty;
 55  
 56  /** Used to infer the `Object` constructor. */
 57  var objectCtorString = funcToString.call(Object);
 58  
 59  /**
 60   * Used to resolve the
 61   * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
 62   * of values.
 63   */
 64  var objectToString = objectProto.toString;
 65  
 66  /** Built-in value references. */
 67  var getPrototype = overArg(Object.getPrototypeOf, Object);
 68  
 69  /**
 70   * Checks if `value` is object-like. A value is object-like if it's not `null`
 71   * and has a `typeof` result of "object".
 72   *
 73   * @static
 74   * @memberOf _
 75   * @since 4.0.0
 76   * @category Lang
 77   * @param {*} value The value to check.
 78   * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
 79   * @example
 80   *
 81   * _.isObjectLike({});
 82   * // => true
 83   *
 84   * _.isObjectLike([1, 2, 3]);
 85   * // => true
 86   *
 87   * _.isObjectLike(_.noop);
 88   * // => false
 89   *
 90   * _.isObjectLike(null);
 91   * // => false
 92   */
 93  function isObjectLike(value) {
 94    return !!value && typeof value == 'object';
 95  }
 96  
 97  /**
 98   * Checks if `value` is a plain object, that is, an object created by the
 99   * `Object` constructor or one with a `[[Prototype]]` of `null`.
100   *
101   * @static
102   * @memberOf _
103   * @since 0.8.0
104   * @category Lang
105   * @param {*} value The value to check.
106   * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
107   * @example
108   *
109   * function Foo() {
110   *   this.a = 1;
111   * }
112   *
113   * _.isPlainObject(new Foo);
114   * // => false
115   *
116   * _.isPlainObject([1, 2, 3]);
117   * // => false
118   *
119   * _.isPlainObject({ 'x': 0, 'y': 0 });
120   * // => true
121   *
122   * _.isPlainObject(Object.create(null));
123   * // => true
124   */
125  function isPlainObject(value) {
126    if (!isObjectLike(value) ||
127        objectToString.call(value) != objectTag || isHostObject(value)) {
128      return false;
129    }
130    var proto = getPrototype(value);
131    if (proto === null) {
132      return true;
133    }
134    var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;
135    return (typeof Ctor == 'function' &&
136      Ctor instanceof Ctor && funcToString.call(Ctor) == objectCtorString);
137  }
138  
139  module.exports = isPlainObject;