Nithyashree B L
Nithyashree B L

Reputation: 99

Can you think of a way to call hasOwnProperty on an object that has its own property by that name?

This is my code

let map = {one: true, two: true, hasOwnProperty: true};

console.log(map.hasOwnProperty("one"));//error map.hasOwnProperty is not a function

The above code should return true. How to achieve this?

Upvotes: 2

Views: 629

Answers (3)

Rohìt Jíndal
Rohìt Jíndal

Reputation: 27192

One suggestion : hasOwnProperty is really a bad property name.

But still if you want to work with it. There are few ways to achieve this :

  • By using Object.hasOwn()

    let map = {one: true, two: true, hasOwnProperty: true};
    
    console.log(Object.hasOwn(map, "one")); // true

  • By using Object.prototype.hasOwnProperty.call()

    let map = {one: true, two: true, hasOwnProperty: true};
    
    console.log(Object.prototype.hasOwnProperty.call(map, "one")); // true

Upvotes: 0

Ahmad
Ahmad

Reputation: 884

You can use apply

const map = {one: true, two: true, hasOwnProperty: true};
console.log(Object.hasOwnProperty.apply(map,[ "one"]));

or call

const map = {one: true, two: true, hasOwnProperty: true};
console.log(Object.hasOwnProperty.call(map,"one"));

or bind

const map = {one: true, two: true, hasOwnProperty: true};
console.log(Object.hasOwnProperty.bind(map)('one'));

Upvotes: 0

T.J. Crowder
T.J. Crowder

Reputation: 1074276

There are a couple of ways:

  1. Object.prototype.hasOwnProperty.call(map, "one").

  2. The brand-new Object.hasOwn(map, "one"), if your target environments support it (it's easily polyfilled if not), which was added precisely because of this issue.

Example:

let map = {one: true, two: true, hasOwnProperty: true};

console.log(
    "Object.prototype.hasOwnProperty.call:", 
    Object.prototype.hasOwnProperty.call(map, "one")
);
if (Object.hasOwn) {
    console.log("Object.hasOwn:", Object.hasOwn(map, "one"));
} else {
    console.log("Object.hasOwn not supported in this environment yet");
}

There are also some methods on Reflect that are useful for these things, such as Reflect.getOwnPropertyDescriptor (Object has a similar method), which would return an object that had value: true on it (because one is a data property, not an accessor property).


Note that, unfortunately, even these static methods can be replaced, so at some point you just have to trust that the environment isn't actively set up to lie to you. :-) For what it's worth, here's an example of a compromised environment:

let map = {one: true, two: true, hasOwnProperty: true};

console.log("Setting up the lies");
const originalHasOwnProperty = Object.prototype.hasOwnProperty;
const originalHasOwn = Object.hasOwn;

Object.prototype.hasOwnProperty = function(propName) {
    if (this === map && propName === "one") {
        return false; // lie
    }
    return originalHasOwnProperty.call(this, propName);
};

Object.hasOwn = function(obj, propName) {
    if (obj === map && propName === "one") {
        return false; // lie
    }
    return originalHasOwn.call(Object, obj, propName);
};

console.log(
    "Object.prototype.hasOwnProperty.call:", 
    Object.prototype.hasOwnProperty.call(map, "one")
);
if (Object.hasOwn) {
    console.log("Object.hasOwn:", Object.hasOwn(map, "one"));
} else {
    console.log("Object.hasOwn not supported in this environment yet");
}

Detecting modifications of the original methods can be complex, so if you decide to try to do that, look for well-researched solutions with solid-looking citations. Normally, though, it's overkill. I note it here just for completeness.

Upvotes: 4

Related Questions