16

As an example am I allowed to use the same variable and parameter? What issues can I run into?

Sample code

function mytask(name,title){
            var name = name;
            var title = title;
            var showalert = ("Hi " + name + " your job title is " + title);
            console.log(showalert);
            return showalert;
        }

document.write(mytask("dan", "administrator"));
20
  • 1
    Why would you ever want to do this? Why not just use the parameter value directly? Commented Jun 19, 2012 at 23:09
  • 1
    There's really no point to declaring new variables just to receive the parameter values. You can just use the param variables directly. Commented Jun 19, 2012 at 23:09
  • 2
    The only reason to redeclare a variable to the same name is, perhaps, to offer a default: var name = name || 'Jeff'; (or, maybe, name = name ? name : 'Jeff';), but only in cases where the paramater's optional. Commented Jun 19, 2012 at 23:13
  • 1
    @PeanutsMonkey: just for kicks, here's a demo: JS Fiddle: http://jsfiddle.net/davidThomas/w4VJt/ showing the only reason I could think of for doing it; though note the var is not required. Commented Jun 19, 2012 at 23:25
  • 1
    Because it's already been defined as an argument/parameter being passed to the function. Commented Jun 19, 2012 at 23:43

7 Answers 7

8

Well in javascript you can think that, scopes are defined my curly brackets: { And }, and inside a scope variables can be redefined, so look at:

function x(){
  var name=3;
  var name=4;
  console.log(name); // output is: 4
}
x();

But this is just half true, actually what happens is that the interpreter goes over the code, and moves all var statements to the beginning, while they're assigned an undefined (and all arguments are defined and taken from stack), and then the code you wrote will run. So any var after the first is simply ignored. And the code you wrote is equal to:

function mytask(name,title){
   var name = arguments[0];
   var title = arguments[1];
   name = name;
   title = title;
   var showalert = ("Hi " + name + " your job title is " + title);
   console.log(showalert);
   return showalert;
}

document.write(mytask("dan", "administrator"));

So your re-deceleration, and assignment is redundant. Anyway - the scope is not changing, nothing else will differ.

Edit

The interpreter goes over your code, with executing anything, any var x = y; statement will split into var x = undefined; and x=y;. And the var x = undefined; will be moved to the top of the code. And the x=y; will be at the same place as the original statement. If you didn't understand the stuff about the stack, don't bother, that's how compilers convert function calls to assembly - it's worth knowing in case you have time; but not THE important thing here.

Anyway - just after those changes, and maybe some optimizations are made, the resulting code is executed. This is not the code you wrote, but an equal one. What you pointed out in redefining the arguments is an edge case where this transformations become visible.

Sign up to request clarification or add additional context in comments.

5 Comments

Could you please elaborate what you mean by "Moves all var statements to the beginning, while they're assigned an undefined (and all arguments are defined and taken from stack), and then the code you wrote will run"?
Okay just to clearly understand what you mean I'll regurgitate. Let me know if I have misunderstood. If I have the function as in my question where the parameter and variable share the same declaration, you mean to say the interpreter would split name = name into name = undefined and name = name. Is that right?
I did not understand the bit about stack but will definitely gloss over it. I did not however understand what you meant by Anyway - just after those changes, and maybe some optimizations are made. What changes are you referring to? What optimizations are made? Are these made by the interpreter?
@PeanutsMonkey Take a look at this or just search for hoisting - that is the formal name of that transformation I was talking about.
var name = arguments[0]; var title = arguments[1]; refer variable Hoisting
2

Think about it this way:

var name = name;

The only way name can be set to the value of name is if name is already defined. There's no need to do it twice if name already has the value you want.

Comments

2

Well, I suppose some explanation won't hurt. )

First, all the function's params are already declared as local for this function. (it's a bit more complex, but let's say this explanation covers most of it). So it's really no use defining them again: they won't become 'more local' after it. ))

Second, it's possible to write var name = name within the function(name) for the same reasons why it's possible to write var name = 123; var name = 345;. The second var will be just silently ignored.

And if you write var name = 123; var name = name;, you'll just waste some keystrokes - as, again, it's the same as you write name = name; somewhere in your code. )

And that, btw, explains messing up the arguments. See, name is actually an alias for its element.

5 Comments

What do you mean by "The second var will be just silently ignore" as well as explains messing up the arguments?
Would you like me to explain how hoisting works in more details?
@buffer What's "this"?
Re-assign a function argument inside it's scope e.g. function change(a) { a = 2}. Also see stackoverflow.com/a/6433583/781695
It's different situation; a is treated the same way any local variable (i.e., defined within the function) is. The question you linked is mostly about arguments object.
1

Sure you can run into problems. Take a look at this.

function mytask(name,title){
            console.log(name);
            console.log(title)
            var name = "oops";
            var title = "rawr";
            console.log(name);
            console.log(title)
}

mytask("dan", "administrator");

Apart from being very confusing, calling console.log(name); gives us two different results (because we redefined it). It's allowed, but it's not a good idea to do.

Edit: Interestingly (I didn't know this), doing the above screws up the implicit arguments[] array as well. For example, doing:

for( var i = 0; i < arguments.length; ++i ) {
    console.log(arguments[i]);
}

somewhere inside our function (post-reassignment) still outputs oops and rawr. Obviously, this is a bad, bad idea.

Comments

1

Actually there's no reason to do it. Once you pass them to the function, they are initialized and you can use them without reassigning them to other variables.

Comments

1

You can use variables with the same name as the parameters, as the value will be the same anyway, unless the variable with the same name will have a different value than the parameter.

Comments

0

<script>

    //this function returns what you give as argument
    function func1(name1) {
        let name1 = "mess shahadat"; //can't declare name, cause already getting name as parameter. thus this gives error if you define a variable same name as parameter with let. cause you can't redeclare let variable in javascript
    }

    document.write(func1("mike"))


</script>

in javascript, function parameters works like local variables. inside function, if you declare variable with var keyword and use same name as parameter, then it will return undefined. and if you declare the variable with let keyword, you will get an error. cause let variables are not redeclarable.

so don't use the same variable name as parameter when you need the variable with the same name to have a different value than the parameter, cause unknownly it can become a bug in your project.

example:

<script>

    //constructor function
    let mobile = function (modelNo, ram, price) {
        this.model = modelNo;
        this.ram = ram;
        let price = price + 1000; //can't declare price, cause already getting price as parameter. and let variables are not redeclarable
        this.price2 = function () { return price };
        this.totalPrice = function () { return "total price is: " + this.price2 }
    }

    let samsung = new mobile("samsung dous", "2gb", 3000);

    document.write(samsung.price2());

</script>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.