Reputation: 313
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
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
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