lightspeed
lightspeed

Reputation: 313

Difference between the two ways object methods can reference object properties

There are two ways of having object methods reference object properties:

let i = {a: 'apple', b: function(){return i.a}}
let j = {a: 'apple', b: function(){return this.a}}

console.log(i.b())  // apple
console.log(j.b())  // apple

What are the pros/cons of these two approaches to referencing object properties??

Upvotes: 0

Views: 49

Answers (2)

Ahmet Can Güven
Ahmet Can Güven

Reputation: 5462

Actually, these functions are not doing the same thing.

Let's consider the first one.

let i = {a: 'apple', b: function(){return i.a}}

You define a function function(){return i.a} which will return a value from object i. Whenever or wherever its called, it will return the value from object i. It is totally independent of scope. You can't reuse this function as a method of a prototype. Because i is always i. It may be useful if you are not using arrow functions to secure your call context.

On the other hand, the other function is different.

let j = {a: 'apple', b: function(){return this.a}}

You are using this so it will access to property a based on its context.


Making everything more clear with an example. Let's say that I have a sheep and dog objects with a property sound.

const dog = {
   sound: 'woof-woof'
};

const sheep = {
   sound: 'Meaeeeeee'
};

Now I am defining a function makeSound

function makeSound {
   alert(this.sound)
}

Now I want to use makeSound for both animals. All I have to do is calling this function by giving it a context.

makeSound.call(sheep) // -> Meaeeeeee
makeSound.call(dog) // -> woof-woof

this helped me to reuse this function for the different type of objects. This is where prototypal inheritance came from.

Upvotes: 2

Mark
Mark

Reputation: 92440

They mean different things. The first one returns the a property of some variable i that's in scope. The fact that the object is also named i means it works as expected. But that's not guaranteed. For example:

let i = {a: 'apple', b: function(){return i.a}}
let j = i
i = {a: "potato"}

console.log(j.b()) // apple or potato?

So long as you expect the function to look into the scope, find an i and return it's a prop, then this works as expected. But it doesn't mean, return the a prop of the object in this function.

Then second does mean that so long as it's called with i.b(), but this doesn't refer to the object where the function was defined — it's value is determined the context of the function call. For example

let i = {a: 'apple', b: function(){return this.a}}
let j = {a: 'potato'}
j.b = i.b

console.log(j.b()) // apple or potato

One isn't better than the other, they are different ideas and can serve different function.

Upvotes: 3

Related Questions