【问题标题】:Why should I use javascript call method?为什么要使用javascript调用方法?
【发布时间】:2019-10-17 15:57:38
【问题描述】:

我正在尝试理解 javascript 中的 callapply 方法。但我不明白为什么要使用它。

var person = {
   fullName: function() {
      return this.firstName + " " + this.lastName;
 }
}

var person1 = {
 firstName:"John",
 lastName: "Doe"
}
var person2 = {
 firstName:"Mary",
 lastName: "Doe"
}
var x = person.fullName.call(person1);  

我可以不使用 call 和 apply 来做这个例子。

var person = {
   fullName: function(firstName, lastName) {
     return firstName + " " + lastName;
 }
}
var person1 = {
  firstName:"John",
  lastName: "Doe"
}
var person2 = {
  firstName:"Mary",
  lastName: "Doe"
}
var x = person.fullName(person1.firstName, person1.lastName); 

或者我不明白这个例子。

function Product(name) {
  this.name = name;
}

function Pizza(name) {
   Product.call(this,name);
}

const pizza = new Pizza("Margherita");

当我想到这个例子时,我可以用原型来做。为什么使用呼叫或申请?谢谢

【问题讨论】:

  • @Rup 是正确的
  • 好的,我修好了。现在可以查了吗?
  • 好吧,我完全改变了样本。我想知道的是我应该在哪里实际使用它? @Rup
  • 您使用.call,因此方法的this 上下文在其原始上下文之外的另一个上下文中被调用。顺便说一句,如果你只想要一个new Product,在最后一个例子中使用原型也是一种浪费。

标签: javascript apply call


【解决方案1】:

一个很好的用例是当您想“借用”具有不同上下文的函数时。以下面的例子为例,您绝对可以使用继承来为 Cat 提供 bark 函数,但也许您不希望该函数存在于每个实例上,而只想在某些情况下使用它。

function Dog(name) {
    this.name = name
    this.bark = function() {
        console.log('woof' + this.name)
    }
}
const dog = new Dog('spot')

dog.bark() // woofspot


function Cat(name) {
    this.name = name
}
const cat = new Cat('cat')

dog.bark.call(cat) // woofcat

【讨论】:

    【解决方案2】:
    function Product(name) {
      this.name = name;
    }
    
    function Pizza(name) {
       Product.call(this,name);
    }
    
    const pizza = new Pizza("Margherita");
    

    那是inheritance。比萨是一种产品。在其他语言中,例如 PHP,继承看起来像这样:

    class Foo {
    
      public function __construct() {
        // Do stuff specific for Foo
      }
    
    }
    
    class Bar extends Foo {
    
      public function __construct()(
        parent::__construct();
        // Do stuff specific for Bar
      }
    
    }
    

    这里,我们没有extends,为了让它工作,你需要说父构造函数中的this是子构造函数。

    使用call,您可以说出Product() 函数/构造函数中的this 是什么。 在这种情况下,它是 Pizza 对象(新创建的对象 {})。如果不使用callPizza 甚至都没有名字。

    第一个例子也是如此

    var person = {
       fullName: function() {
          return this.firstName + " " + this.lastName;
     }
    }
    
    var person1 = {
     firstName:"John",
     lastName: "Doe"
    }
    var person2 = {
     firstName:"Mary",
     lastName: "Doe"
    }
    var x = person.fullName.call(person1);  
    

    是的,它在没有调用 call 的情况下工作,但并非没有重大变化。

    person.fullName.call(person1); 就像说使用这个函数并用我的 person1 对象置换this。所以最后,就好像你这样做了:

    return person1.firstName + " " + person1.lastName;
    

    至于which one使用

    注意:虽然此函数的语法与 call() 的语法几乎相同,但根本区别在于 call() 接受 参数列表,而 apply() 接受 a单个参数数组

    【讨论】:

    • 我不能对继承做同样的事情吗? @jperl
    • @omerstack 你是什么意思?那已经是继承了。 Pizza 继承自 Product。在 Pizza 中,我们说调用 Product 但使用 Pizza (this) 的上下文。所以 this.name 就像说 (Pizza).name = name;然后您可以在调用 Product 后向 Pizza 添加属性。
    • 我的意思是,我可以使用 Object.create 和原型吗?因为正如我所读,我们使用原型进行继承。
    • @omerstack 请看这个developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/…。它还解释了如何继承产品原型上的方法。
    • @omerstack 原型用于对象实例共享的函数。但是你需要做call来继承构造函数中的属性。
    【解决方案3】:

    据我所知,这完全是您使用的偏好问题,但您必须使用 call 和/或 apply,没有它们就无法做到。

    【讨论】:

    • 我不明白为什么我不能。但如果你说这是一个选择问题,我明白了。
    • 如果您同时删除两者,您应该会看到 @Rup 在 cmets 下发布的内容。
    • 好吧,我完全改变了样本。我想知道的是我应该在哪里实际使用它? @死亡华尔兹
    • @omerstack 看看另一个答案,它比我解释得更好
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-17
    • 2021-12-07
    • 1970-01-01
    • 1970-01-01
    • 2015-04-30
    相关资源
    最近更新 更多