为什么Coffeescript认为阴影是一个坏主意 [英] Why is Coffeescript of the opinion that shadowing is a bad idea

查看:133
本文介绍了为什么Coffeescript认为阴影是一个坏主意的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想切换到Coffeescript一段时间,昨天我以为我终于出售了,但后来我偶然发现了

I've wanted to switch to Coffeescript for a while now and yesterday I thought I'm finally sold but then I stumbled across Armin Ronachers article on shadowing in Coffeescript.

Coffeescript确实现在放弃了阴影,这个问题的一个例子将是如果你对嵌套循环使用相同的迭代器。

Coffeescript indeed now abandoned shadowing, an example of that problem would be if you use the same iterator for nested loops.

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]);
      }
  })();
}

因为cs只声明变量,一旦我不能这样做coffeescript

Because cs only declares variables once I wouldn't be able to do this within coffeescript

阴影已被故意删除,我想了解为什么cs作者想要摆脱这样的功能?

Shadowing has been intentionally removed and I'd like to understand why the cs-authors would want to get rid of such a feature?

更新:这是一个更好的示例为什么Shadowing是重要,源自与此问题相关的问题 on github

Update: Here is a better example of why Shadowing is important, derived from an issue regarding this problem on github

PS:我不是在找一个答案,告诉我我可以只插入简单的Javascript与反馈。

PS: I'm not looking for an answer that tells me that I can just insert plain Javascript with backticks.

推荐答案

p>如果您阅读关于这张票的讨论,您可以看到CoffeeScript的创建者Jeremy Ashkenas,解释一些禁止显式阴影的原因:

If you read the discussion on this ticket, you can see Jeremy Ashkenas, the creator of CoffeeScript, explaining some of the reasoning between forbidding explicit shadowing:


我们都知道动态范围比词法范围差,因为它使它很难理解你的变量的价值。对于动态范围,您无法通过读取周围的源代码来确定变量的值,因为该值完全取决于调用函数时的环境。如果允许和鼓励变量阴影,则不能确定变量的值,而不会在源中向后跟踪到最接近的var变量,因为局部变量的完全相同的标识符在相邻范围中可以具有完全不同的值。在所有情况下,当你想要一个变量,你可以通过简单地选择一个更合适的名称来完成同样的事情。如果一个局部变量名在整个词法范围内有一个单独的值,并且禁止使用阴影,那么更容易理解你的代码。

We all know that dynamic scope is bad, compared to lexical scope, because it makes it difficult to reason about the value of your variables. With dynamic scope, you can't determine the value of a variable by reading the surrounding source code, because the value depends entirely on the environment at the time the function is called. If variable shadowing is allowed and encouraged, you can't determine the value of a variable without tracking backwards in the source to the closest var variable, because the exact same identifier for a local variable can have completely different values in adjacent scopes. In all cases, when you want to shadow a variable, you can accomplish the same thing by simply choosing a more appropriate name. It's much easier to reason about your code if a local variable name has a single value within the entire lexical scope, and shadowing is forbidden.

这是一个非常慎重的选择CoffeeScript通过一个石头杀死两只鸟 - 通过删除var概念来简化语言,并禁止阴影变量作为自然结果。

So it's a very deliberate choice for CoffeeScript to kill two birds with one stone -- simplifying the language by removing the "var" concept, and forbidding shadowed variables as the natural consequence.

如果在CoffeeScript问题中搜索scope或shadowing,您可以看到这一切都会出现。我不会在这里说,但是要点是CoffeeScript Creators相信它会导致更简单的代码,更不容易出错。

If you search "scope" or "shadowing" in the CoffeeScript issues, you can see that this comes up all the time. I will not opine here, but the gist is that the CoffeeScript Creators believe it leads to simpler code that is less error-prone.

好吧,我会赞成一点位:阴影无所谓。你可以想出一些假设的例子,说明为什么两种方法都更好。事实是,有阴影或没有,你需要搜索向上范围链,以了解变量的生命。如果您明确声明变量ala JavaScript,您可能可以更快地短路。但是没关系。如果你不确定在给定函数中有什么变量,你就做错了。

Okay, I will opine for a little bit: shadowing doesn't matter. You can come up with contrived examples that show why either approach is better. The fact is that, with shadowing or not, you need to search "up" the scope chain to understand the life of a variable. If you explicitly declare your variables ala JavaScript, you might be able to short-circuit sooner. But it doesn't matter. If you're ever unsure of what variables are in scope in a given function, you're doing it wrong.

阴影 CoffeeScript,不包括JavaScript。如果你实际上需要一个你知道是局部范围的变量,你可以得到它:

Shadowing is possible in CoffeeScript, without including JavaScript. If you ever actually need a variable that you know is locally scoped, you can get it:

x = 15
do (x = 10) ->
  console.log x
console.log x

在实践中出现的机会,有一个相当简单的解决方法。

So on the off-chance that this comes up in practice, there's a fairly simple workaround.

就我个人而言,我更喜欢显式声明每变量方法,并提供以下作为我的argument:

Personally, I prefer the explicitly-declare-every-variable approach, and will offer the following as my "argument":

doSomething = ->
  ...
  someCallback = ->
    ...
      whatever = ->
        ...
        x = 10
        ...

工作伟大。然后突然有一个实习生加入了这一行:

This works great. Then all of a sudden an intern comes along and adds this line:

x = 20
doSomething = ->
  ...
  someCallback = ->
    ...
      whatever = ->
        ...
        x = 10
        ...

bam,代码被破坏,但是破坏不会直到后来出现。糟糕!使用 var ,这不会发生。但是通常隐式范围,除非你另外指定,它会有。所以。无论如何。

And bam, the code is broken, but the breakage doesn't show up until way later. Whoops! With var, that wouldn't have happened. But with "usually implicit scoping unless you specify otherwise", it would have. So. Anyway.

我在一家在客户端和服务器上使用CoffeeScript的公司工作,我从未在实践中听到这种情况。我认为节省的时间,不必在每个地方键入单词 var 大于范围缺陷(从未出现)损失的时间量。

I work at a company that uses CoffeeScript on the client and server, and I have never heard of this happening in practice. I think the amount of time saved in not having to type the word var everywhere is greater than the amount of time lost to scoping bugs (that never come up).

因为写这个答案,我看到这个错误在实际代码中发生了两次。每次发生,它是非常烦人,很难调试。

Since writing this answer, I have seen this bug happen two times in actual code. Each time it's happened, it's been extremely annoying and difficult to debug. My feelings have changed to think that CoffeeScript's choice is bad times all around.

一些像CoffeeScript的JS替代品,例如LiveScript和coco,使用两个不同的赋值运算符: = 可以声明变量,:= 可以修改外部范围中的变量。这看起来像一个更复杂的解决方案,而不仅仅是保留 var 关键字,以及一些东西也不会保持一旦 let 可广泛使用。

Some CoffeeScript-like JS alternatives, such as LiveScript and coco, use two different assignment operators for this: = to declare variables and := to modify variables in outer scopes. This seems like a more-complicated solution than just preserving the var keyword, and something that also won't hold up well once let is widely usable.

这篇关于为什么Coffeescript认为阴影是一个坏主意的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆