Which object does not have `hasOwnProperty` in JavaScript?

transang picture transang · Aug 24, 2018 · Viewed 7k times · Source

With some values, calling hasOwnProperty throws an error.

Let's check the following code:

null.hasOwnProperty('bar') // Error
undefined.hasOwnProperty('bar') // Error
(0).hasOwnProperty('bar') // Returns false

Are there any other variables rather than null and undefined that throws an error when calling with .hasOwnProperty?

The same question for setting an object's property:

null.bar // Error
undefined.bar // Error
(0).bar === undefined // Returns true

=========

Another case where it throws an error in my Node.js environment:

In a browser

'use strict';
(0).bar = 0; // Nothing happens

In Node.js v.10.3.0:

(0).bar = 0; // Nothing
'use' strict';
(0).bar === undefined; // Returns true
true.bar === undefined; // Returns true
''.bar = '';// STILL NOTHING HAPPENS
(0).bar = 0; //TypeError: Cannot create property 'bar' on number '0'
(true).bar = true; // TypeError: Cannot create property 'bar' on boolean 'true'

========

Eventually, I found Check if a value is an object in JavaScript:

if (obj instanceof Object) obj.hasOwnProperty(...) // Or set a property on it

This solution totally fulfills my needs.

Answer

Bhojendra Rauniyar picture Bhojendra Rauniyar · Aug 24, 2018

Using hasOwnProperty as a property name:

var foo = {
  hasOwnProperty: function() {
    return false;
  },
  bar: 'Here be dragons'
};

foo.hasOwnProperty('bar'); // always returns false

// Use another Object's hasOwnProperty
// and call it with 'this' set to foo
({}).hasOwnProperty.call(foo, 'bar'); // true

// It's also possible to use the hasOwnProperty property
// from the Object prototype for this purpose
Object.prototype.hasOwnProperty.call(foo, 'bar'); // true

Also take care to the latest draft:

When the hasOwnProperty method is called with argument V, the following steps are taken:

  1. Let P be ? ToPropertyKey(V).
  2. Let O be ? ToObject(this value).
  3. Return ? HasOwnProperty(O, P).

NOTE

The ordering of steps 1 and 2 is chosen to ensure that any exception that would have been thrown by step 1 in previous editions of this specification will continue to be thrown even if the this value is undefined or null.