hol
hol

Reputation: 8423

airnb/javascript: What does this mean: "These methods may be shadowed by properties ..."?

I try to understand the following sentence at github airnb/javascript

https://github.com/airbnb/javascript#objects--prototype-builtins

Why? These methods may be shadowed by properties on the object in question

What is meant with "shadowed" in this case?

For easier reference here the full section:

3.7 Do not call Object.prototype methods directly, such as hasOwnProperty, propertyIsEnumerable, and isPrototypeOf.

Why? These methods may be shadowed by properties on the object in question - consider { hasOwnProperty: false } - or, the object may be a null object (Object.create(null)).

// bad
console.log(object.hasOwnProperty(key));

// good 
console.log(Object.prototype.hasOwnProperty.call(object,key));

// best
const has = Object.prototype.hasOwnProperty; // cache the lookup once, in module scope. 
/* or */ 
import has from 'has'; 
// ...
console.log(has.call(object, key));

Upvotes: 1

Views: 149

Answers (3)

Dmitry Shvetsov
Dmitry Shvetsov

Reputation: 803

When you creating an object

const anObject = {};

it almost always has the Object in prototype chain. It allow the created object to have access to functions defined in Object like hasOwnProperty.

Shadowed means a method or a property that defined in the created object has the same name as those functions or properties that in prototype chain.

Example of shadowing:

const obj = {};
obj.hasOwnProperty // => ƒ hasOwnProperty() { [native code] }

obj.hasOwnProperty = 'don\'t do this!';
obj.hasOwnProperty // => "don't do this!"

Upvotes: 2

Suren Srapyan
Suren Srapyan

Reputation: 68665

See an example. Here I have created an function with name hasOwnProperty directly on the my object. So it hides the parent version of the hasOwnProperty. In it I write a logic which will return everytime true. So anybody who will use my object and tries to detect if it has some property in it (he/she doesn't know I have shadowed the base on) he can have a logic errors in his/her code. Because JS will try to find the function first in the object and call that version which actually does another work.

But when you call this method from the Object.prototype, which is the correct version of the method, and pass the context to it, it will work correctly, because it will call the Object.prototypes method with name hasOwnProperty and just pass this object as the context of the method. So from here is the warning that you must use this methods from the prototype.

Actually you can also change the Object.prototype version of the method, but there is a rule, Not change the prototypes of the built in objects.

const object = { 
  hasOwnProperty: function() {
      return true;
  }
};

console.log(object.hasOwnProperty('name')); 
console.log(Object.prototype.hasOwnProperty.call(object, 'name'));

The first log says that there is a property name in the object, but it isn't. This may cause a logic error. The second one uses the correct version and gives a correct result.

Upvotes: 2

Quoc-Anh Nguyen
Quoc-Anh Nguyen

Reputation: 5066

Consider some example below:

const object = { hasOwnProperty: false }
console.log(object.hasOwnProperty(key)) // Error: hasOwnProperty is not a function

or

const object = null
console.log(object.hasOwnProperty(key)) // Error: Can not read property of null

So you can understand shallowed in this case is your object methods in prototype is shallowed by an object property (has the same name)

Upvotes: 2

Related Questions