简体   繁体   中英

How does scoping work in javascript? Why does this function work?

I simply do not understand how the "reset" function works here, and I created this script! The "value" variable on line 8...how is that reset to zero and then picked up by the iterator("value++") on the next line? I would have thought the iterator, and the whole script, was outside of the function's scope?

var timer = null, 
    interval = 1000,
    value = 48;

$("#start").click(function() {
  if (timer !== null) return;
  timer = setInterval(function () {
      $("#reset").click(function() { value = 0} );
      value++;
      $("#input").val(value);
  }, interval); 
});

$("#stop").click(function() {
  clearInterval(timer);
  timer = null
});

JSFIDDLE

In your example, you don't even need any fancy explanations involving closures or binding.

You've defined value with global scope. The function passed to setInterval repeatedly increments that value and updates the #input element, and the function bound to #reset sets it to zero. Both functions have access to variables with global scope.

In your example, value is defined at the global scope so it can be accessed anywhere. So upon clicking the element reset , the global value is set back to 0.

Changing it to:

$("#reset").click(function() { var value = 0} );

would create a seperate value variable scoped only to that function.

The scope of your var value is accessible by all other functions inside that function (the document ready in your case (if you have it at all, otherwise it's totally a global var name.)).
Another way is to define your var to the window Object** which will make it also global to all outer and other functions

Examples with the "usual" way and with some Immediately Invoked Functions Expressions to see clearly the difference:

var text = "Hello!"; // Global

(function sayhello(){
   alert(text); // Ok, works
})();

http://jsbin.com/apuker/2/edit

(function defineVar(){
  var text = "Hello!"; // Private
})();

(function sayhello(){
   alert(text); // No dice
})();

http://jsbin.com/apuker/4/edit

(function defineVar(){
  window.text = "Hello!";
})();

(function sayhello(){
   alert(text); // Watta?... IT WORKS!
})();

and BTW, Your code should look like: (note the #reset and the nicer if (timer) return; )

var timer = null, 
    interval = 1000,
    value = 48;

$("#start").click(function() {
  if (timer) return;           // return - if timer is not null (true).
  timer = setInterval(function () {
      value++;
      $("#input").val(value);
  }, interval); 
});

$("#reset").click(function() {
    value = 0;
});

$("#stop").click(function() {
  clearInterval(timer);
  timer=null;
});

As of ECMAScript 5, there is only function scope. All variables are global by default, unless declared using the 'var' keyword in which case they are only visible in the function they were declared.

In your script, although you declare 'value' using the var keyword, you declare it outside of any function effectively making it a global variable.

FYI: There are currently plans to introduce the ability to declare variables with block scope in ECMAScript 6 via the new 'let' keyword.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM