开发者

Do conditional statements introduce block scope for variables in JavaScript?

I have a minor problem with a JavaScript snippet that I hope you can help me solving it.

var z=0;

function xyz() { 
    if (!z) {
        z+=5;
        var h=15; // The problem resides here
    }
    else { 
        var f=h+7;
        alert(f);
         }
    z++;
    return z;    
}

When I registered this function to a click event handler on a button element, I was expecting to see by the second iteration of function execution an alert message displaying

22

What I had was a NaN message indicating that the variable h wasn't defined despite the explicit declaration statement within the if branch but when I omitted the var keyword, suddenly the function behaved :)

It's really puzzling for me as I am pretty sure that JS doesn't natively support block scoping except when using the let keyword introduced by Mozilla browsers. I am also darn sure that declaring variables using the var keyword creates local scope for them and therefore they become exclusively accessible within the function in which they are defined.

So, why on the world I have to declare h as a global variable for the function to work?

Any help would be very appreciated as I am new to Web Design and I am coming from graphic design background.

Note: Actually,this was not the real life problem that I faced during coding. I was trying to create a ticker that updates every 10 seconds automatically using the setInterval() method and then suppressing it when the user browses the headlines manually and when he's done, the script takes over once again.

I thought that a more generic and simple example is more suitable to explain the solution without getting into the details of the methods/properties used.

=======

UPDATE

I think I got it now. Functions don't have memories and thus can't remember values generated from previous calls. What I was doi开发者_JAVA百科ng actually is storing the value generated from the first call in a global variable that can be accessed in future calls. But I'm wondering is there any elegant way to achieve the same result other than using global variables?


No. In fact all your local variables are initialized at the beginning of your function. Your example code will be executed like this:

function xyz() { 
    var h;
    var f;
    if (!z) {
        z+=5;
        h=15;
    }
    else { 
        f=h+7;
        alert(f);
         }
    z++;
    return z;    
}

You get NaN because in f=h+7 h is declared but it's value is undefined.

There is a more elegant way: using objects. There are may ways you can create objects, I use the most compact method here:

function MyObject() {
    this.z = 0;
    // it's safer to initialize all your variables (even if you dn't use the initial value)
    this.h = 0;
    this.f = 0;

    this.xyz = function () {
        if (!this.z) {
            this.z += 5;
            this.h = 15;
        } else { 
            this.f = this.h + 7;
            alert(this.f);
        }
        this.z++;
        return this.z;    
    }
}

var o = new MyObject();
o.xyz();
o.xyz();

There are many-many docs about OOP in JS if you are interested.


Nope, only functions have a local scope. Do not put anything in global scope unless you absolutely have to.


You can use closures to get the result (I think) you want, e.g.

var xyz = (function() {
  var z = 0;
  var h;

  return function() { 
    var f;

    if (!z) {
      z += 5;
      h = 15;

    } else { 
      f = h + 7;
      alert(f);
    }
    return ++z;
  }
})();

the first time nothing is shown, after that 22 is always shown and z increments 6, 7, 8, and so on.

-- Rob

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜