views:

212

answers:

5
+3  Q: 

function arguments

Hi, if I have:

function Foo(f)
{
   var f = f;    
}

here inside the function variable f is local to the Foo (it has a function scope) but the variable f in argument list that is named in the same way why it isn't in conflict may be because it is bound inside the Foo.arguments object?

In other languages we cannot declare an argument variable with the same name as a local variable.

How is this name ambiguity resolved? Or, How do you reference each of the two distinct 'f' variables later in the method?

+2  A: 

Once you declare a new variable with the same name of an old one, it overrides it and you cannot reference both at the same time.

You should either change the parameter or the variable name.

Seb
A: 

In firefox I noticed that declaring the new variable didn't do any harm it's almost as if the stament wasn't there for this

  <script type="text/javascript">

  function saymessage(f) {
    alert(f);
    var f = f;
    alert(f);
    alert(this.f);
  }
  </script>
</head>

<body >

  <!-- Insert Body Here -->
<button  id='link' textToShow="Hidden message text" onclick="saymessage('Hello World')">Click me </button>

</body>

I got "Hello World" on the 1st and 2nd alerts and "undefined" on the third

ferrari fan
yes because this bound to window object in that function context and is undefined because doesn't exists any variable declared as window.f = ...
xdevel2000
+5  A: 

There is no way to solve this problem, except renaming one of them, or storing the value in another variable.

function foo(f) {
    console.log(f); // --> 11
    console.log(arguments); // --> array [11]
    var f=10;
    console.log(f); // --> 10
    console.log(arguments); //even this is now array [10]
}
foo(11);
Hippo
actually that's wrong :Dthe first time you log(f) it will produce undefined, as js spec hoists all var declarations to the beginning of the function (the assignment stays in the same position)
olliej
+4  A: 

JavaScript does a couple of things that aren't obviously intuitive - the one you're interested in is called "hositing" - JS moves var declarations to the top of a function, where they serve the sole purpose of reserving this variable name as a local variable in function scome. Sometimes, this leads to lots of weirdness. If the variable name is already reserved as a local variable - say, because it's an argument, the var declaration gets dropped entirely.

Another unintuitive part of JS is how it deals with argument variables and the `arguments' object (which are a bit special, as Hippo showed). That's not necessarily what you're interested in, though - what's important for your example is that arguments also declare that variable name as local to the function.

The result of all this is that when you have a var f' as well as an argument name f', the `var f' gets dropped, and your example is equivalent to:

function Foo(f) {
   f = f;
}

You can see this in Hippo's example, because:

function foo(f) {
    console.log(f); // --> 11
    console.log(arguments); // --> array [11]
    var f = 10;
    console.log(f); // --> 10
    console.log(arguments); // --> [10] (!!!)
}

Is equivalent to:

function foo(f) {
    var f;
    console.log(f); // --> 11
    console.log(arguments); // --> array [11]
    f = 10;
    console.log(f); // --> 10
    console.log(arguments); // --> [10] (!!!)
}

Is equivalent to:

function foo(f) {
    console.log(f); // --> 11
    console.log(arguments); // --> array [11]
    f = 10;
    console.log(f); // --> 10
    console.log(arguments); // --> [10] (!!!)
}

For more details, read up section 10.1.3 - Variable Instantiation (bottom of p.37) in ECMA-262, the JS specification.

Andrey Fedorov
+1  A: 

here inside the function variable f is local to the Foo (it has a function scope) but the variable f in argument list that is named in the same way why it isn't in conflict may be because it is bound inside the Foo.arguments object?

No, it is not bound on arguments: arguments is only an Array of positional argument values, you can't get ‘arguments.f’ out of it.

Arguments passed into a function by name become local variables. The “var f” in a function with argument ‘f’ is implicit.

When you declare ‘var f’ on a variable that is already local, nothing happens. Your code is identical to:

function Foo(f)
{
    f = f;
}

In other languages we cannot declare an argument variable with the same name as a local variable.

In JavaScript, as long as there is one use of “var x” in a scope block, any use of ‘x’ in that block is local. You can happily declare ‘var’ on the same variable in the same scope again and again, but it doesn't do anything.

bobince
may be function scope...JS doesn't have a scope block
xdevel2000