What’s the deal with Object.prototype.hasOwnProperty.call()?
Tags: javascript, prototype, webdev, inheritance
Published: 2020-04-24 16:37:13

I am sure you might have seen the following line of code either while reading someone’s code or in a library.
```js
Object.prototype.hasOwnProperty.call(objRef, 'propName');
```

And now you are wondering what on earth this code is doing. You start doubting your JavaScript skills. Don’t worry. You are at the right place.

I have chosen this piece of code for a few purposes, and by demystifying this, we will understand the following things: 
1. What is Object.prototype?
2. How an object can borrow a function without implementing it or having it in its prototype chain?
3. Why do we access `hasOwnProperty` on the Object's prototype and **not** on the instance itself?

If this sounds intriguing to you, let’s get started. 

### 1. Object.prototype
[**Prototypal inheritance**](https://medium.com/javascript-scene/the-two-pillars-of-javascript-ee6f3281e7f3) is one of the main pillars of JavaScript language which allows an object to inherit methods and properties on its prototype. You can think of the prototype as a template.

> Prototypal inheritance allows an object to inherit methods and properties on its prototype.

It’s better to understand with an example:

```js
var obj = {name: 'aman'}
obj.hasOwnProperty(‘name’)  // returns true
```
As you see, we haven’t defined any `hasOwnProperty` on our `obj` object but we managed to invoke it. How is it possible? 🤔

This is possible due to the **prototypal inheritance** and the way **prototype chain** works.  Let’s dig a bit deeper. 

When we created our literal object `obj`, its *prototype* was set to **Object.prototype**. To verify we can see:
```js
Object.getPrototypeof(obj) === Object.prototype // returns true
```

 [[Prototype]] is an inheritance relationship between objects. In our case, it’s the relation between the *obj* and Object’s *prototype*.  

The prototype chain looks like: 
```js
// Prototype chain
obj —-> Object.prototype ——> null
```
When we try to access a property on an object, the interpreter first looks for it on the object itself. If it couldn’t find the property on the object, it will traverse up until it finds the property in the chain. 

Thus, when we invoked `hasOwnProperty()`, the interpreter couldn't find it on the `obj`, so it traverses up in the chain and finds it on **Object.prototype**.

Additionally, We can set up or override the prototype chain however we want by using **Object.setPrototypeOf()** method or by using **Object.create()**. 

Consider this example: 
```js
var person = {name: 'peter'};
var PersonPrototype = {getName: function(){ return this.name; }}; 

// Setting person's prototype 
Object.setPrototypeOf(person, PersonPrototype);

// Trying to access getName() method will cause a prototype chain lookup (aka prototype delegation) 
// and finds it on PersonPrototype. 
person.getName(); // 'peter'
```

### 2. Borrowing a function 
Let's imagine If I have a following function and an object: 
```js
function sayHello() { console.log(`Greetings ${this.name}`) }
var a = {name: 'peter'};
```

How would you make the object `a` borrow `sayHello`, and invoke the correct *name* in the greetings? We don't want `a` to implement `sayHello` or have it anywhere on its prototype chain. 🤔

The answer is via `call` and `apply` method available on **Function.prototype**. 

In JavaScript, every function we create inherits from **Function.prototype**. 
And as we have just learned that via prototype chain, we can use *call* method on all function objects. 💡

> In JavaScript, every function we create inherits from Function.prototype. 

The syntax of [call method](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call) is: 

```js
// 'call' method is available on Function.prototype
func.call(objRef, ...args); 
```

The first argument is an object who wants to borrow this function followed by the list of arguments for that function.

So, for *a* to borrow `sayHello`, all we have to do is use `call` method on `sayHello` passing *a* as an argument: 
```js
sayHello.call(a); // Greetings peter 
```
 ---
### 3. Object.prototype.hasOwnProperty vs instance.hasOwnProperty

After a lightweight tutorial on Prototypal inheritance and borrowing functions, finally, it's time to demystify why one would use *hasOwnProperty* on the *Object.prototype* and not on the object instance.

As we mentioned above that we can control the prototype chain ourselves. One way is to use [Object.create()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create) method while creating Object instance. 

```js
// Object.create() accepts an argument which becomes
// the prototype for newly created object.
var a = Object.create(null); // Setting `null` as prototype for 'a'. 

// Adding a 'name' property on the instance
a.name = 'peter';

// Using `hasOwnProperty` method would cause an error
a.hasOwnProperty('name'); //🚫 throws a TypeError: a.hasOwnProperty is not a function
```
Trying to invoke `hasOwnProperty` throws an error as there's no such method available on the object or its prototype chain. The prototype chain was like: 
```js
// Prototype chain
a ---> null
```
You may be wondering why someone would create an object like this. But the irony is that in JavaScript you are allowed to be as crazy as you want 🔥. 

Imagine you are creating a library and exposing a function that accepts an object as an argument. If your function makes use of `hasOwnProperty` directly on the object being passed from outside, it could break your code if someone passes an object with `null` as its prototype. 

Consequently, to guard this problem we can use *function borrowing* technique we previously learned. The passed-in object argument can borrow `hasOwnProperty` available on Object.prototype as we previously learned via `call` method. 🚀😇.

```js
// Will not break your code if 'a' has a null prototype. ✅
Object.prototype.hasOwnProperty.call(a, 'name'); // true; 
```
---
### Summary
- Every object literal inherits from **Object.prototype**. This allows you to invoke some of the methods available like `hasOwnProperty`. 
- We can override/create the prototype chain with the help of **Object.setPrototypeOf** method and via **Object.create(prototype)**. 
- Every function inherits from **Function.prototype** allowing you to consume methods like `call`, `apply`, and `bind`. 
- An object can borrow other functions without implementing them or having them in their prototype chain. This can be achieved by using `call` or `apply` method available on `Function.prototype`.
- Use `Object.prototype.hasOwnProperty.call(objRef, 'propName')` to guard the **TypeError** when objRef has `null` prototype. 


That's all for now. I hope you have enjoyed reading this article and learned a few things. Go and share this achievement with others 😍.