简体   繁体   中英

Using call in JavaScript vs Returning by simple function

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

  1. Why second snippet gives error instead of answer?
  2. What is the importance of using 'call' in the first method? Cannot simple function also return the same answer?
  3. What is advantage of call over apply and bind if same used in this example?

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.

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)();

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 over apply and bind 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).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM