在 JavaScript 中使用调用 vs 通过简单函数返回

Using call in JavaScript vs Returning by simple function

根据对象数据计算总量的两种方法:

代码段 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);

片段 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);

结果 1:

398

结果二:

我的查询

  1. 为什么第二个片段给出了错误而不是答案?
  2. 在第一种方法中使用 'call' 的重要性是什么?难道简单的函数也return一样的答案吗?
  3. 如果在此示例中使用相同的调用,那么调用 applybind 有什么优势?

我会尽力解答您的每一个问题。

Why second snippet gives error instead of answer?

因为,您正在使用 IIFE,但您什么都不是 return。如果你没有明确地 return javascript 中的某些东西(在一个函数中),它被暗示为 return 未定义。因此你的错误 "cannot... of undefined"。所以你想要return那个函数,你在里面有。

What is the importance of using 'call' in the first method? Cannot simple function also return the same answer?

调用(和应用)的重要性在于能够 "bind" 上下文。因此,在您的代码段 1 中 - 您是否看到对 this 的引用。好吧,当您使用 call 调用函数时 - 您是 "binding" goodsthis 的上下文。所以,当你说 this.price 时,你就是在说 goods.price。因为 call 使您能够做到这一点。

What is advantage of call over apply and bind if same used in this example?

其他人可能知道其中的复杂性,但我相信 call 在这种情况下没问题。如果,除了设置 "context" 之外,您还传递了一些参数 - 就像一个数组,那么您将使用 applybind return 的使用是一个新函数,因此存在内存开销。它就像部分应用程序 - 你给出一个参数,上下文 - 它 return 是一个新函数 - 等待。我会说在你的用法中, call 是完美的。我想听听其他人的想法。

Why second snippet gives error instead of answer?

你的第二个片段抛出错误,因为你忘记在 IIFE 中添加它:

return { calculatePriceNow : calculatePriceNow };

What is the importance of using 'call' in the first method? Cannot simple function also return the same answer?

call 的重要性在于,它意味着您正在使用 面向对象 方法而不是 功能性方法。使用 this 与使用参数都是完成任务的同样正确的方法。它们仅在相关的编程范式上有所不同。在 JavaScript 中,使用参数的功能方法变得越来越流行。

What is advantage of call over apply and bind if same used in this example?

在这种情况下使用 applycall 一样好,尽管 bind 在调用它之后需要一组额外的括号:

var result = shoppingCart.calculatePrice.bind(goods)();

这里试图澄清一些事情。

<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>

备注

不会工作;为什么?因为函数 calculatePrice 取决于它的作用域 (this)

var result = shoppingCart.calculatePrice(goods); 
console.log(result);

会工作;为什么?我们正在调用函数,使用 call

显式地给出它的作用域
var result = shoppingCart.calculatePrice.call(goods);
console.log(result);

会工作;为什么?我们正在调用函数,使用 call

显式地给出它的作用域
var result = shoppingCart.calculatePrice.apply(goods);
console.log(result);

它是如何与 callapply 一起工作的?

它们正在我们传递给函数的参数 goods 的范围内执行 calculatePrice。这样做,函数 calculatePricethis 的用法引用对象 goods.

callapply 的区别?

apply() 方法使用给定的 this 值和作为数组提供的 arguments 调用函数 另一方面,call() 方法调用具有给定 this 值和 arguments 单独提供的函数

到查询:

Why second snippet gives error instead of answer?

就像上面提到的,当我们这样调用时,scope 是函数的,而不是 'argument'

What is the importance of using 'call' in the first method? Cannot simple function also return the same answer?

简单的回答是我们给它 explicit scope 使用 call

What is advantage of call over apply and bind if same used in this example?

call()apply()bind() 是 JavaScript 中所有 function 对象的一部分。它的用法如上所述有所不同。 call()apply() 的优点是调用方法的灵活性(比如使用不同的参数)。