【问题标题】:Why we need call or apply method in javascript, when we can directly call the method?当我们可以直接调用方法时,为什么我们需要在javascript中调用或应用方法?
【发布时间】:2020-11-29 21:46:53
【问题描述】:

为什么我们在 java 脚本中使用 Call 或 Apply 方法?除了发送参数来调用方法的差异之外,普通方法调用和使用 Call/Apply 之间的主要区别是什么?如果你能用一个场景解释一下吗?

【问题讨论】:

    标签: javascript arrays function apply call


    【解决方案1】:

    在处理对象时会很有帮助,我建议你阅读这两个指南,它们解释得很好:

    【讨论】:

      【解决方案2】:

      您可能知道,函数是 JavaScript 中的一等公民。这意味着您可以将它们作为参数传递给其他函数。

      在某些情况下,您正在处理依赖于上下文的 methods。例如:

      const button = document.querySelector('button');
      const getRect = button.getBoundingClientRect;
      
      getRect(); // TypeError...
      
      // You have to pass a context fo that function
      getRect.call(button);
      

      还有一些其他函数可以传递上下文。请看applybindcall...

      另一个使用callapply 的好例子是monkey-patching

      // Save the original console.log() method
      var log = console.log;
      
      console.log = function() {
         // Invoke the original method with an additional parameter
         log.apply(console, [(new Date()).toString()].concat(arguments));
      };
      

      Kyle Simpson 在他的系列中有很好的解释You don't know JS

      【讨论】:

        【解决方案3】:

        我可以举两个例子来解释为什么它很重要。假设您有一个如下所示的类:

        class MyClass {
          myProp = 'Hello World';
          myMethod() {
            console.log(this.myProp);
          }
        }
        

        假设您想在按钮单击事件上调用myMethod。这就是你要做的:

        const myInstance = new MyClass();
        document.querySelector('button').addEventListener('click', myInstance.myMethod);
        

        现在有一个问题:使用addEventListener,执行上下文发生了变化,this 指的是元素而不是类实例(它没有myProp 属性)。我该如何改回来?在这种情况下,您可以使用bind

        document.querySelector('button').addEventListener('click', myInstance.myMethod.bind(myInstance));
        

        这实质上将引用更改回类。这只是一个例子。可能有很多示例,您希望更改方法的当前执行上下文。我们再举一个例子:

        假设有一个第三方函数需要访问某些类成员。

        第三方函数需要目标实例的namelastname 属性。

        function getFullName() {
          return this.name + ' ' + this.lastname;
        }
        

        如果在没有callapply 的情况下执行此方法,则该方法假定存在此函数的当前实例(在本例中为window),并搜索当前对象的属性。但是可能存在您可能想要更改此行为的要求。假设您有提供namelastname 属性的类,并且您想利用此方法的功能。这是你可以做的:

        class MyName {
          name = 'Tom';
          lastname = 'Hanks';
        }
        
        getFullName.apply(new MyName()); // --> 'Tom Hanks'
        

        所以你看到callapply 是如何有帮助的。您可以参考 Zer0 的回答了解更多关于callapplybind 的信息。

        【讨论】:

          【解决方案4】:

          这是关于应用与调用中的 this 上下文。应用你可以在数组中传递参数。

          【讨论】:

            【解决方案5】:

            你还可以通过它从不同的对象中访问同名的函数,例如 toString() 或任何你喜欢的:

            class MyObject {
                constructor(operator) {
                    this.operator = operator;
                }
                
                calculate(a, b) {
                    switch(this.operator) {
                        case '+': return a + b;
                        case '-': return a - b;
                        case '*': return a * b;
                        case '/': return a / b;
                    }
                }
            }
            
            const operators = [
                new MyObject('+'),
                new MyObject('-'),
                new MyObject('*')
            ];
            for (const op of operators) {
                const func = op['calculate'];
                console.log(func.call(op, 1, 1));
            }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2013-03-31
              • 1970-01-01
              • 1970-01-01
              • 2020-03-18
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多