English 中文(简体)
Confusing operation of JavaScript `var` keyword
原标题:

I’ve run into a very strange (to me) problem with the var keyword. I’ve reduced it to a fairly minimal test case, and found it’s exhibited in Node.js (thus, V8 and Chrome), Safari 4’s inspector (thus, Nitro), and FireBug (obviously, SpiderMonkey). I was originally preparing a bug report, but since it’s so widely displayed, I’m going to assume that I completely misunderstand how JavaScript is supposed to scope and look up variables.

The test case is very small, and on GitHub here: http://gist.github.com/260067. The only difference between the first and second example is the inclusion of the var keyword.

Here, as well, is a similar test case that exhibits the same ‘problem’ in a different way: https://gist.github.com/698b977ee0de2f0ee54a

Edit: To preclude any more answers attempting to explain how cascading scope works, I’m intimately familiar with that. My problem, is that I don’t understand why the following code ‘works’ (in that it alert()s ‘outer,’ followed by ‘inner,’ and then again ‘outer’):

(function(){
  var foo =  outer ;
  alert("Outer `foo`: " + foo);

  (function(){
    foo =  inner ;
    alert("Inner `foo`: " + foo);

    var foo;
  })();

  alert("Outer `foo`: " + foo);
})();

The var foo; occurs in a completely irrelevant position to the re‐assignment of foo; so why does it affect that assignment in a very substantial way?

最佳回答

The thing is that unlike other languages, JavaScript creates all variables at the start of a function. This means that the code:

(function(){
    if(myVar == undefined){
        alert(myVar);
    }
    if(myVar == undefined){
        var myVar = 5;
    }
})();

Is actually compiled and interpreted as

(function(){
    var myVar;
    if(myVar == undefined){
        alert(myVar);
    }
    if(myVar == undefined){
        myVar = 5;
    }
})();

To create a variable and only have it available inside an if or loop block, you have to use let, which is a new JavaScript feature. I m not sure how many browsers implement it yet (Firefox 3.5 does if you use <script type="text/javascript;version=1.7">).

(function(){
    if(myVar == undefined){
        alert(myVar);
    }
    if(myVar == undefined){
        let myVar = 5;
    }
})();
问题回答

var exports doesn t work exactly like local variables in many languages. It declares exports as local variable in the whole function instead of just the enclosing block (even though it appears after the first usage), so the function argument with the same name is hidden.

Edit: the let keyword works more conventionally (it declares a variable only for the containing block) but it isn t available in all versions of JavaScript.

the inclusion of var means that the assignment of the {} is done to a local variable exports instead of the global variable exports, which means it has no effect.





相关问题
selected text in iframe

How to get a selected text inside a iframe. I my page i m having a iframe which is editable true. So how can i get the selected text in that iframe.

How to fire event handlers on the link using javascript

I would like to click a link in my page using javascript. I would like to Fire event handlers on the link without navigating. How can this be done? This has to work both in firefox and Internet ...

How to Add script codes before the </body> tag ASP.NET

Heres the problem, In Masterpage, the google analytics code were pasted before the end of body tag. In ASPX page, I need to generate a script (google addItem tracker) using codebehind ClientScript ...

Clipboard access using Javascript - sans Flash?

Is there a reliable way to access the client machine s clipboard using Javascript? I continue to run into permissions issues when attempting to do this. How does Google Docs do this? Do they use ...

javascript debugging question

I have a large javascript which I didn t write but I need to use it and I m slowely going trough it trying to figure out what does it do and how, I m using alert to print out what it does but now I ...

Parsing date like twitter

I ve made a little forum and I want parse the date on newest posts like twitter, you know "posted 40 minutes ago ","posted 1 hour ago"... What s the best way ? Thanx.

热门标签