为什么 cat.setName = setName 和 setName.apply pig 的输出,['Babe

Why the output of cat.setName = setName and setName.apply pig, ['Babe'] is same. Even why It is neccessary to have them in code

本文关键字:setName Babe 输出 cat apply pig 为什么      更新时间:2023-09-26

大家好,因为我是咖啡脚本的新手,所以我对此感到困惑。我正在关注一本"https://www.montecassino.org/images/data/attachments/0000/0014/CoffeeScript.pdf"的书,其中有一个代码示例,如下所示

setName = (name) -> 
    @name = name
    console.log(@name)
    console.log(name)
cat = {}
cat.setName = setName
cat.setName "Manu"
console.log(cat.name)
pig = {}
setName.apply pig, ['Babe']
console.log(pig.name)

在上面的代码中,我不明白发生了什么。有一个函数为对象分配名称。但是cat.setName = setName和setName.apply pig,['Babe']的目的和含义是什么。这些行具有相同的含义,那么它们之间有什么区别。如果我问一个愚蠢的问题,我很抱歉,但我完全困惑。任何帮助将不胜感激。谢谢

两个片段——一个关于cat的片段和一个关于pig的片段——都在完成同样的事情。他们正在为两个不同的对象调用 setName 函数。不同之处在于,在cat示例中,setName 函数成为 cat 对象的一部分,而在pig示例中,setName 函数应用于pig,但实际上并未成为pig对象的一部分。

如果您将其分解为多个部分并推理每个部分在做什么,可能会更清楚地理解。

第一部分定义了一个函数,由setName引用:

setName = (name) -> 
  @name = name
  console.log(@name)
  console.log(name)

如您所见,它需要一个参数,name . @name = name如果您不熟悉CoffeeScript,可能会有点混乱。CoffeeScript 中的@符号等同于 JavaScript 中的this符号。在JS中,它会是this.name,但在CS中快捷方式是@name。调用setName函数时,@(或this)将引用调用setName函数的上下文。

cat = {}
cat.setName = setName
cat.setName "Manu"
console.log(cat.name)

在上面的块中,首先创建一个名为 cat 的空对象。它最初没有函数或属性。然后我们向其添加上面定义的setName函数。

这可以写成:

cat = {}
cat.setName = (name) ->
  @name = name
  console.log(@name)
  console.log(name)

但是由于已经定义了setName函数,我们可以简单地设置cat.setName它。

当调用cat.setName "Manu"时(或者写成cat.setName("Manu"),CoffeeScript 中的括号是可选的),setName 内部的@是指setName所属的对象。 setName(适当地)在cat对象上设置一个名为 name 的属性。如果你要console.log(cat),你会看到这样的东西:

{ setName: [Function], name: 'Manu' }

我们取了一个名为 cat 的空对象,然后给了它一个名为 setName 的函数,然后称为 setName ,它在其上设置了一个属性:name

pig示例具有相同的结果,但语法略有不同:

pig = {}
setName.apply pig, ['Babe']
console.log(pig.name)

在此示例中,我们在setName上调用 apply 函数(它本身就是一个函数)。调用setName.apply pig, ['Babe']会将函数setName应用于对象pig,并带有一个参数数组。通过将pig作为第一个参数传递给apply,我们实际上是在告诉apply:在setName内部,每当你看到@时,我们实际上是在谈论pig

apply的第二个参数是调用setName时使用的参数数组。此数组中只有一个元素,它与setName接受的参数数匹配。 ['Babe']是一个只有一个参数的参数数组:'Babe'

这个和cat示例之间的重要区别在于,我们没有setName pig对象的一部分。事实上,console.log(pig)产生

{ name: 'Babe' }

看?没有setName功能。我们仅将该函数应用于pig对象。您注意到在 cat 示例中的行cat.setName = setName --我们没有为pig这样做。

您可以查看Mozilla的apply JS函数文档以获取更多背景信息:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply?redirectlocale=en-US&redirectslug=JavaScript%2FReference%2FGlobal_Objects%2FFunction%2Fapply

就其价值而言,我并不经常看到在生产CoffeeScript代码中使用apply的例子。如果你真的坚持理解这一点,那么继续前进并稍后重新审视它可能是值得的。