最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

memory - Javascript concerns of using 'var' on an already-existing variable - Stack Overflow

programmeradmin1浏览0评论

Let's say I start up a var for an Object in my code

var base = {x:Infinity, y:Infinity};

and later in the same scope I do

var base = {x:0, y:0}

I get that I can re-use the existing variable, but I'm trying to iterate on a point.

  1. Does this cause any problems for the current scope as far as memory is concerned?
  2. Would there be any problems if these are in different scopes?
  3. Is the general rule to never use var on an already-existing variable?
  4. If I did this several (thousands) of times, would I run into any "funky" issues?

Let's say I start up a var for an Object in my code

var base = {x:Infinity, y:Infinity};

and later in the same scope I do

var base = {x:0, y:0}

I get that I can re-use the existing variable, but I'm trying to iterate on a point.

  1. Does this cause any problems for the current scope as far as memory is concerned?
  2. Would there be any problems if these are in different scopes?
  3. Is the general rule to never use var on an already-existing variable?
  4. If I did this several (thousands) of times, would I run into any "funky" issues?
Share Improve this question asked Dec 5, 2011 at 21:11 JacksonkrJacksonkr 32.3k42 gold badges189 silver badges289 bronze badges 3
  • #3 - yes, but mostly because its easier to maintain such code. – c69 Commented Dec 5, 2011 at 21:20
  • please post a bit more example code to show how you'd be using this. It's a bit ambiguous whether variable hoisting will be an issue or whether each variable is in a separate closure. – zzzzBov Commented Dec 5, 2011 at 21:20
  • Using var multiple times for the same variable could be useful when debugging. – Thomas Eding Commented Dec 5, 2011 at 21:26
Add a ment  | 

4 Answers 4

Reset to default 7
  1. It releases its hold on the old value, so it can be potentially garbage collected. I say potentially, because objects can be referenced by different variables.

  2. If they're in different scopes, the inner base will shadow the outer one (assuming you're talking about nested scopes), so the old value will not be overwritten. Shadowing is usually best avoided.

  3. Generally, within the same scope, yes but that's more of a coding style aspect. It won't make an effective difference in the execution since there's only one declaration no matter how many times you declare the same var in the same scope.

  4. Depends. Are you talking about overwriting in a loop? If you no longer need the current value, it shouldn't be an issue.


To be clear, when you do this:

var base = {x:Infinity, y:Infinity};

var base = {x:0, y:0}

What's really happening is this:

var base;  // declaration is hoisted

base = {x:Infinity, y:Infinity};  // new object is referenced by base

base = {x:0, y:0}  // previous object is released, and new object is referenced

Note that when I talk about scope and var, I'm talking specifically about function scope. In standard JavaScript/ECMAScript implementations, there is no block scope, so there's no special meaning when using var in a for statement for example.

As mentioned by @Charles Bailey, Mozilla has let, which does allow scoping in blocks, but it would require that specific keyword. The var statement doesn't recognize the block with respect to variable scope.

There is absolutely no problem in doing that. Afterall, variables declared within a function (-context) are just part of the such called Activation Object (ES edition 3). It is a little bit different in ES5, but for this part it is basically the same.

You are just overwritting a property, in an Object (not a Javascript object, but from the underlaying js engine).

So again, that is not a problem at all (even if its unusual und looks confusing).

If you declare a variable in another "scope" (which basically means, another function here), it is also no problem. Each (execution) context is pletely on its own and cannot interfer with another context, unless we are talking about closures and stuff. But even then, if you have several functions and parent context which all have the same named variable, the lookup process (name resolution) always begins in your local scope (the Activation object from the current context) and after that, it goes into the "scope chain".

I guess that should answer 3.) and 4.) also. You "can" re-var a variable, but it makes no sense. So I'd just remend to don't do it anymore.

  1. The var keyword provides scope to a variable. The only scope available to JavaScript at this time is function scope. If the variable is already scoped to this function then setting with the var keyword again does nothing.

  2. JavaScript is lambda language, which means variables declared in a higher scope are available to functions inside that higher scope. Providing a variable from a higher scope with the var keyword in a lower function scope could be harmful, because you have now created a local variable that may be intended as closure. Consider the following two examples:

    var a = function () {
        var b = 3,
            c = function () {
                var d = 5;
                b = 5;
                return d + b; // this is 10
            };
        return c() + b; // this is 10 + 5, or 15
    };
    var a = function () {
        var b = 3,
            c = function () {
                var b = 5,
                    d = 5;
                return d + b; // this is 10
            };
        return c() + b; // this is 10 + 3, or 13
    };
    

I said unintentionally altering variable scope is potentially harmful, because it will confuse how your code works from how you think it should work.

The general rule is one var declaration per function, and that var declaration belongs at the top of the function:

function foo() {
  var bar;
}

The reason to do it is to avoid confusion that could be caused by variable hoisting.

An example of where this matters is with closure context for callbacks:

//this looks like it will count up, but it wont
function foo() {
  var i;
  for (i = 0; i < 10; i++) {
    var bar = i;
    setTimeout( function () {
      console.log(bar);
    }, 1000 * i);
  }
}

//this is actually what's happening behind the scenes
//hopefully you can see why it wont work
function foo() {
  var i, bar;
  for (i = 0; i < 10; i++) {
    bar = i; //bar is in the same scope as i
    setTimeout( function () {
      //when this is called `i` and `bar` will both have a value of 9
      console.log(bar);
    }, 1000 * i);
  }
}

If you've got a sub-function, you can declare a new variable of the same name, which will remain for the scope of that sub-function:

function foo() {
  var bar;
  function baz() {
    bar = 2;
  }
  bar = 1;
  baz();
  console.log(bar); //output will be 2 because baz operated in the outer scope
}


function foo() {
  var bar;
  function baz() {
    var bar;
    bar = 2;
  }
  bar = 1;
  baz();
  console.log(bar); //output will stay 1 because baz operated in its own scope
}

If your example code is along the lines of:

function foo() {
  var base = {x:Infinity, y:Infinity};
  ...some code...
  var base = {x:0, y:0};
}

It will actually execute as:

function foo() {
  var base;
  base = {x:Infinity, y:Infinity};
  ...some code...
  base = {x:0, y:0};
}
发布评论

评论列表(0)

  1. 暂无评论