nim*_*rod 15 javascript coffeescript
我现在想切换到Coffeescript一段时间,昨天我觉得我终于卖了但是后来我偶然发现了Armin Ronachers关于Coffeescript阴影的文章.
Coffeescript确实现在放弃了阴影,如果你对嵌套循环使用相同的迭代器就会出现这个问题.
var arr, hab, i;
arr = [[1, 2], [1, 2, 3], [1, 2, 3]];
for(var i = 0; i < arr.length; i++){
var subArr = arr[i];
(function(){
for(var i = 0; i < subArr.length; i++){
console.log(subArr[i]);
}
})();
}
Run Code Online (Sandbox Code Playgroud)
因为cs只声明变量一次我无法在coffeescript中执行此操作
阴影已被故意删除,我想了解为什么cs-authors想要摆脱这样的功能?
更新:这是一个更好的例子,说明为什么影子很重要,源于github上有关此问题的问题
PS:我不是在找一个答案告诉我,我可以用反引号插入普通的Javascript.
Ian*_*nry 25
如果您阅读有关此故障单的讨论,您可以看到CoffeeScript的创建者Jeremy Ashkenas解释了禁止显式阴影之间的一些推理:
我们都知道,与词法范围相比,动态范围很差,因为它很难推断变量的值.对于动态范围,您无法通过读取周围的源代码来确定变量的值,因为该值完全取决于调用函数时的环境.如果允许并鼓励变量阴影,则无法确定变量的值而不在源中向后追踪到最接近的var变量,因为局部变量的完全相同的标识符在相邻的范围中可以具有完全不同的值.在所有情况下,当您想要隐藏变量时,只需选择一个更合适的名称即可完成相同的操作.如果局部变量名在整个词法范围内具有单个值,并且禁止使用阴影,则更容易推理您的代码.
因此,CoffeeScript非常谨慎地选择一石二鸟 - 通过删除"var"概念简化语言,并禁止阴影变量作为自然结果.
如果您在CoffeeScript问题中搜索"范围"或"阴影",您可以看到它始终出现.我不会在这里提出意见,但要点是,CoffeeScript Creators认为它会导致更简单的代码,而不易出错.
好的,我会稍微考虑一下:阴影并不重要.你可以拿出人为的例子来说明为什么这两种方法都更好.事实是,无论是否有阴影,您都需要搜索范围链以"了解"变量的生命周期.如果您明确地将变量声明为JavaScript,则可能会更快地进行短路.但没关系.如果您不确定给定函数中的变量范围是什么,那么您做错了.
阴影是可能在CoffeeScript中,不包括JavaScript.如果您确实需要一个您知道的本地范围的变量,您可以得到它:
x = 15
do (x = 10) ->
console.log x
console.log x
Run Code Online (Sandbox Code Playgroud)
因此,在实际出现这种情况的可能性很小,有一个相当简单的解决方法.
就个人而言,我更喜欢显式声明每变量的方法,并将提供以下作为我的"参数":
doSomething = ->
...
someCallback = ->
...
whatever = ->
...
x = 10
...
Run Code Online (Sandbox Code Playgroud)
这非常有效.然后突然一个实习生来了并添加了这一行:
x = 20
doSomething = ->
...
someCallback = ->
...
whatever = ->
...
x = 10
...
Run Code Online (Sandbox Code Playgroud)
而且,bam,代码被破坏了,但破损直到后来才出现.哎呦!有var,那不会发生.但是,除非你另有说明,否则"通常是隐含的范围",它会有.所以.无论如何.
我在一家在客户端和服务器上使用CoffeeScript的公司工作,我从未听说过这种情况在实践中发生过.我认为,无需在var任何地方输入单词所节省的时间量大于确定错误的时间(从未出现过).
自写这个答案以来,我已经看到这个错误在实际代码中发生了两次.每次发生时,它都非常烦人且难以调试.我的感受已经发生变化,认为CoffeeScript的选择时机已经很糟糕.
一些类似CoffeeScript的JS替代品,例如LiveScript和coco,为此使用两个不同的赋值运算符:=声明变量和:=修改外部作用域中的变量.这似乎是一个更复杂的解决方案,而不仅仅是保留var关键字,而且一旦let被广泛使用也不会很好.
这里的主要问题不是阴影,它的CoffeeScript混淆变量初始化和变量重新分配,并且不允许程序员准确地指定它们的意图
当咖啡脚本编译器看到时x = 1,它不知道你的意思
我想要一个新的变量,但是我忘了我已经在一个较高的范围内使用了这个名字
要么
我想将值重新分配给我最初在文件顶部创建的变量
这不是你禁止在一种语言中使用阴影的方式.这就是你如何制作一种语言来惩罚那些意外地重复使用变量名称并且难以检测到错误的用户.
CoffeeScript可能被设计为禁止阴影,但保持声明和任务分开var.编译器只会抱怨这段代码:
var x = blah()
var test = ->
var x = 0
Run Code Online (Sandbox Code Playgroud)
"变量x已存在(第4行)"
但它也会抱怨这段代码:
x = blah()
test = ->
x = 0;
Run Code Online (Sandbox Code Playgroud)
"变量x不存在(第1行)"
但是,由于var被删除,编译器不知道你的意思是"声明"还是"重新分配"并且无法帮助.
对两个不同的东西使用相同的语法并不"简单",即使它看起来像它.我推荐Rich Hickey的演讲,简单易学,他深入了解为何如此.