为什么 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
大家好,因为我是咖啡脚本的新手,所以我对此感到困惑。我正在关注一本"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
的例子。如果你真的坚持理解这一点,那么继续前进并稍后重新审视它可能是值得的。