Sam Kong
Sam Kong

Reputation: 5820

Confusion about CoffeeScript variable scope

I am trying to understand how CoffeeScript variables are scoped. According to the documentation:

This behavior is effectively identical to Ruby's scope for local variables.

However, I found out that it works differently.

In CoffeeScript

a = 1
changeValue = -> a = 3
changeValue()
console.log "a: #{a}" #This displays 3

In Ruby

a = 1
def f
  a = 3
end
puts a #This displays 1

Can somebody explain it, please?

Upvotes: 6

Views: 442

Answers (2)

Blacksad
Blacksad

Reputation: 15432

Ruby's local variables (starting with [a-z_]) are really local to the block they are declared in. So the Ruby behavior you posted is normal.

In your Coffee example, you have a closure referencing a. It's not a function declaration.

In your Ruby example, you don't have a closure but a function declaration. This is different. The Ruby equivalent to your Coffee is:

a = 1
changeValue = lambda do
   a = 3
end
changeValue()

In closures, local variables present when the block is declared are still accessible when the block is executed. This is (one of the) powers of closures!

Upvotes: 8

Paul Simpson
Paul Simpson

Reputation: 2514

The a variable being used inside the changeValue function is the global a variable. That CoffeeScript will be compiled into the following JavaScript:

var a, changeValue;
a = 1;
changeValue = function() {
  return a = 3;
};
changeValue();
console.log("a: " + a);

In order for changeValue to not alter the a variable (i.e. use a local variable), you would either need to have an argument to the function named a (which would create a as a variable local to that function) or declare a as a local variable inside the function using var a = 3; (not sure what the CoffeeScript for that would be, I'm not a CoffeeScript guy).

Some examples of JavaScript variable scope.

Upvotes: 0

Related Questions