Reputation: 8240
These are the 2 methods to calculate total amount based on object data:
Snippet 1
var shoppingCart = (function(){
function calculatePriceNow() {
return this.price * this.amount;
};
return {
calculatePrice : calculatePriceNow
}
})();
var goods = {
name : 'hammer',
price: 199,
amount : 2
};
var result = shoppingCart.calculatePrice.call(goods);
console.log(result);
Snippet 2
var shoppingCart = (function(){
function calculatePriceNow(obj) {
return obj.price * obj.amount;
};
})();
var goods = {
name : 'hammer',
price: 199,
amount : 2
};
var result = shoppingCart.calculatePriceNow(goods);
console.log(result);
Result 1:
398
Result 2:
My Query
Upvotes: 0
Views: 84
Reputation: 11807
I'll try to address each of your questions.
Why second snippet gives error instead of answer?
Because, you are using an IIFE, yet you are return nothing. If you do not explicitly return something in javascript (in a function) it is implied to return undefined. Thus your error "cannot... of undefined". So you'd want to return that function, that you have inside of it.
What is the importance of using 'call' in the first method? Cannot simple function also return the same answer?
The important of call (and apply) is the ability to "bind" the context. So, in your snippet 1 - do you see the references to this
. Well, when you call the function with call
- you are "binding" the context of goods
to this
. So, when you say this.price
, you are saying goods.price
. Because call
enables you to do that.
What is advantage of call over apply and bind if same used in this example?
Others might know the intricacies, but I believe call
is fine in this context. IF, you were passing some arguments in addition to setting the "context" - like an array, then you'd use apply
. The usage of bind
returns a new function, so there is a memory cost there. It is like partial application - you give an argument, the context - and it returns a new function - waiting. I'd say in your usage, call is perfect. I'd like to hear what others think.
Upvotes: 1
Reputation: 5539
Here is an attempt to clear up things a bit.
<script>
var shoppingCart = (function () {
function calculatePriceNow() {
return this.price * this.amount;
};
return {
calculatePrice: calculatePriceNow
}
})();
var goods = {
name: 'hammer',
price: 199,
amount: 2
};
// will not work; Why? Because the function `calculatePrice` depends on their scope (`this`)
var result = shoppingCart.calculatePrice(goods);
console.log(result);
// will work; Why? We are calling the function giving it's scope explicitly using `call`
var result = shoppingCart.calculatePrice.call(goods);
console.log(result);
// will work; Why? We are calling the function giving it's scope explicitly using `apply`
var result = shoppingCart.calculatePrice.apply(goods);
console.log(result);
// How did it work with `call` and `apply`?
// They are executing `calculatePrice` in the scope of the argument `goods` which we passed to the function
// Doing so, the usage of `this` inside the function `calculatePrice` refer to the object `goods`
// Difference between `call` and `apply`?
// From MDN:
// The `apply()` method calls a function with with a given `this` value and `arguments` provided as array
// On the other hand, `call()` method calls a function with a given `this` value and `arguments` provided individually
</script>
Notes:
Will not work; Why? Because the function calculatePrice
depends on its scope (this
)
var result = shoppingCart.calculatePrice(goods);
console.log(result);
Will work; Why? We are calling the function giving it's scope explicitly using call
var result = shoppingCart.calculatePrice.call(goods);
console.log(result);
Will work; Why? We are calling the function giving it's scope explicitly using call
var result = shoppingCart.calculatePrice.apply(goods);
console.log(result);
How did it work with call
and apply
?
They are executing calculatePrice
in the scope of the argument goods
which we passed to the function. Doing so, the usage of this
inside the function calculatePrice
refer to the object goods
.
Difference between call
and apply
?
The apply()
method calls a function with with a given this
value and arguments
provided as array
On the other hand, call()
method calls a function with a given this
value and arguments
provided individually
To the queries:
Why second snippet gives error instead of answer?
Like mentioned above, when we call like that the scope
is that of the function, not of the 'argument'
What is the importance of using 'call' in the first method? Cannot simple function also return the same answer?
Simple answer would we that we are giving it explicit scope
using call
What is advantage of
call
overapply
andbind
if same used in this example?
call()
, apply()
and bind()
are part of all function
object in JavaScript. The usage of it varies as mentioned above.
The advantages over call()
and apply()
is the flexibility on calling a method (say with different arguments).
Upvotes: 1
Reputation: 33486
Why second snippet gives error instead of answer?
Your second snippet is throwing an error because you forgot to add this inside the IIFE:
return { calculatePriceNow : calculatePriceNow };
What is the importance of using 'call' in the first method? Cannot simple function also return the same answer?
The importance of call
is that it means you're using an object-oriented approach instead of a functional approach. Using this
vs. using a parameter are both equally correct ways to accomplish the task. They only differ by their associated programming paradigm. In JavaScript, it's becoming much more popular to use the functional approach, using the parameter.
What is advantage of call over apply and bind if same used in this example?
Using apply
would be equally as good as call
in this case, though bind
would require an extra set of parentheses after you call it:
var result = shoppingCart.calculatePrice.bind(goods)();
Upvotes: 1