Files
lodash/isPlainObject.js
Tim Dorr b36f21cbaf Faster/simpler isPlainObject check (#3483)
Faster/simpler isPlainObject check.

This runs up the prototype chain to check equivalency. When run in a cross-realm environment (differing contexts, iframes, etc), this ensures we're checking the value's prototype matches its context-specific instance of Object. 

This is faster than calling `toString()` on the constructor. There's still the `baseGetTag()` call, which does its own `toString()`, but this swaps out one for cross-realm stuff. It's also a bit simpler to understand, I think.
2017-11-08 11:11:20 -08:00

45 lines
1.0 KiB
JavaScript

import baseGetTag from './.internal/baseGetTag.js'
import isObjectLike from './isObjectLike.js'
/**
* Checks if `value` is a plain object, that is, an object created by the
* `Object` constructor or one with a `[[Prototype]]` of `null`.
*
* @since 0.8.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
* @example
*
* function Foo() {
* this.a = 1
* }
*
* isPlainObject(new Foo)
* // => false
*
* isPlainObject([1, 2, 3])
* // => false
*
* isPlainObject({ 'x': 0, 'y': 0 })
* // => true
*
* isPlainObject(Object.create(null))
* // => true
*/
function isPlainObject(value) {
if (!isObjectLike(value) || baseGetTag(value) != '[object Object]') {
return false
}
if (Object.getPrototypeOf(value) === null) {
return true
}
let proto = value
while (Object.getPrototypeOf(proto) !== null) {
proto = Object.getPrototypeOf(proto)
}
return Object.getPrototypeOf(value) === proto
}
export default isPlainObject