Check if a value is an object in JavaScript

后端 未结 30 3788
臣服心动
臣服心动 2020-11-22 05:06

How do you check if a value is an object in JavaScript?

30条回答
  •  挽巷
    挽巷 (楼主)
    2020-11-22 05:57

    After reading and trying out a lot of implementations, I've noticed that very few people try to check for values like JSON, Math, document or objects with prototype chains longer than 1 step.

    Instead of checking the typeof of our variable and then hacking away edge-cases, I thought it'd be better if the check is kept as simple as possible to avoid having to refactor when there's new primitives or native objects added that register as typeof of 'object'.

    After all, the typeof operator will tell you if something is an object to JavaScript, but JavaScript's definition of an object is too broad for most real-world scenarios (e.g. typeof null === 'object'). Below is a function that determines whether variable v is an object by essentially repeating two checks:

    1. A loop is started that continues as long as the stringified version of v is '[object Object]'.
      I wanted the result of the function to be exactly like the logs below, so this is the only "objectness"-criteria I ended up with. If it fails, the function returns false right away.
    2. v is replaced with the next prototype in the chain with v = Object.getPrototypeOf(v), but also directly evaluated after. When the new value of v is null, it means that every prototype including the root prototype (which could very well have been the only prototype inside the chain) have passed the check in the while loop and we can return true. Otherwise, a new iteration starts.

    function isObj (v) {
      while (     Object.prototype.toString.call(v) === '[object Object]')
      if    ((v = Object.getPrototypeOf(v))         === null)
      return true
      return false
    }
    
    console.log('FALSE:')
    console.log('[]                   -> ', isObj([]))
    console.log('null                 -> ', isObj(null))
    console.log('document             -> ', isObj(document))
    console.log('JSON                 -> ', isObj(JSON))
    console.log('function             -> ', isObj(function () {}))
    console.log('new Date()           -> ', isObj(new Date()))
    console.log('RegExp               -> ', isObj(/./))
    
    console.log('TRUE:')
    console.log('{}                   -> ', isObj({}))
    console.log('new Object()         -> ', isObj(new Object()))
    console.log('new Object(null)     -> ', isObj(new Object(null)))
    console.log('new Object({})       -> ', isObj(new Object({foo: 'bar'})))
    console.log('Object.prototype     -> ', isObj(Object.prototype))
    console.log('Object.create(null)  -> ', isObj(Object.create(null)))
    console.log('Object.create({})    -> ', isObj(Object.create({foo: 'bar'})))
    console.log('deep inheritance     -> ', isObj(Object.create(Object.create({foo: 'bar'}))))

提交回复
热议问题