csは、ループが意図したとおりに機能しなくなった場合にのみ変数を宣言するためです。
それらのループが機能するための意図された方法は何ですか?が空でない場合、の条件while i = 0 < arr.length
は常に真にarr
なるため、無限ループになります。意図したとおりに機能しないループが1つしかない場合でもwhile
(無限ループが探しているものではないと想定):
# This is an infinite loop; don't run it.
while i = 0 < arr.length
console.log arr[i]
i++
配列を順番に繰り返す正しい方法は、次のfor ... in
構成を使用することです。
arr = [[1,2], [1,2,3], [1,2,3]]
for hab in arr
# IDK what "hab" means.
for habElement in hab
console.log habElement
私は、この答えが正接していくように聞こえることを知っています。その主なポイントは、CSが可変シャドウイングを推奨しない理由です。しかし、例が何かに賛成または反対の議論に使用される場合、例は良いはずです。この例は、可変シャドウイングを推奨する必要があるという考えには役立ちません。
更新(実際の回答)
変数シャドウイングの問題について、明確にする価値のあることの1つは、ブロックではなく、異なる関数スコープ間で変数シャドウイングを許可する必要があるかどうかについての議論であるということです。同じ関数スコープ内で、変数は最初に割り当てられた場所に関係なく、スコープ全体を持ち上げます。このセマンティクスはJSから継承されます。
->
console.log a # No ReferenceError is thrown, as "a" exists in this scope.
a = 5
->
if someCondition()
a = something()
console.log a # "a" will refer to the same variable as above, as the if
# statement does not introduce a new scope.
時々尋ねられる質問は、let
キーワードのように変数のスコープを明示的に宣言する方法を追加しないのはなぜですか(したがって、スコープを囲む際に同じ名前の他の変数をシャドウイングする)、または=
常にそのスコープに新しい変数を導入するようにします、そして:=
現在のスコープで変数を宣言せずに、スコープを囲む変数を割り当てるようなものがあります。この動機は、この種のエラーを回避することです。
user = ... # The current user of the application; very important!
# ...
# Many lines after that...
# ...
notifyUsers = (users) ->
for user in users # HO NO! The current user gets overridden by this loop that has nothing to do with it!
user.notify something
変数をシャドウイングするための特別な構文がないというCoffeeScriptの主張は、この種のことを行うべきではないということです。変数に明確な名前を付けます。シャドウイングが許可されたとしても、同じ名前の2つの異なる意味を持つ2つの変数(1つは内部スコープに、もう1つは囲みスコープにある)を持つことは非常に混乱するためです。
コンテキストの量に応じて適切な変数名を使用します。たとえば、トップレベルの変数など、コンテキストがほとんどない場合は、それを説明するために非常に具体的な名前が必要になる可能性がありますcurrentGameState
(特に、定数ではなく、その値が時間とともに変化する); より多くのコンテキストがある場合は、ループ変数のように、(コンテキストがすでに存在するため)わかりにくい名前を使用する必要がありますkilledEnemies.forEach (e) -> e.die()
。
この設計上の決定についてもっと知りたい場合は、これらのHackerNewsスレッドでJeremy Ashkenasの意見を読むことに興味があるかもしれません:link、link ; または、このトピックが議論されている多くのCoffeeScriptの問題:#1121、#2697など。