1

I am reading a section about closures in a JS book, and reached an example in the section showing 'getter/Stetter' functions...

var getValue, setValue;

(function (){

    var secret = 0;

    getValue = function(){
    return secret;
    }
    setValue = function(v){
    secret = v;
    }

})();

setValue(5);
getValue();
5 //get 5

1) I thought omitting 'var' made variables global?

2) From time to time I hear folks talking about 'getters/Setters', What would be a practical use of them?

Thanks!

Antonio Pavicevac-Ortiz
  • 7,239
  • 17
  • 68
  • 141
  • In `setValue`, the `secret` variable could not be found, so it went up through the scope chain until it found it in the outer function. http://stackoverflow.com/questions/1484143/scope-chain-in-javascript – reergymerej Feb 03 '14 at 14:03

3 Answers3

1

Why is the 'secret' variable not global?

Because it is declared using var.

var secret = 0;

I thought omitting 'var' made variables global?

One use of var in a function will make all variables declared in that statement local.

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
1

Why isn't it global?

Javascript has functional scope, so the secret variable exists only within the scope of the function.

var iAmGlobal = true;
iAmGlobalToo = true; // no var made this an implied global

(function () {
  var iExistInThisFunctionsScope = true;
  iAmAnImpliedGlobal = true;  // omitted var attached this to the global scope
}());

Omitting var doesn't necessarily make a variable global. What happens is, when a variable isn't found in the current scope, the parent scope is checked. This happens either until the variable is found, or the global scope is reached. When you accidentally forget var, you often end up with an implied global.

What are some of the problems of "Implied Global variables"?

Why use getters/setters?

Using closures to create getters/setters allows you to control how the variables are modified. Because in Javascript everything is mutable, anything can be changed by any other thing. This seems cool at first, but you soon realize that you have no control over who or what is changing your variables. Getters and setters allow you to hide the variable in the function's scope, so if something wants to change it, it must go through you.

Here's an example of controlling your variables.

function Foo () {
    var privateVar = 1234;

    this.get = function () {
        return privateVar;
    }

    this.set = function (x) {
        // privateVar doesn't exist in this function's scope,
        // but it will be found in the next scope up the chain.
        privateVar = x;
    }
}

// create an instance
var myFoo = new Foo();

// use the getter/setter
console.log(myFoo.get());  // 1234
myFoo.set(999);
console.log(myFoo.get());  // 999

// try to change privateVar outside
// of the getter/setter
myFoo.privateVar = 'not what you think';

// We didn't actually change the var.
console.log(myFoo.get());  // 999

// We added a new property.
console.log(myFoo.privateVar);  // 'not what you think'
Community
  • 1
  • 1
reergymerej
  • 2,371
  • 2
  • 26
  • 32
0

Because it's defined within (function() { ... }). If you want to make it global, declare it alongside your getValue and setValue.

The var keyword simply declares a variable, it doesn't make it global:

var secret = "Global";        // Global variable declaration

function myFunction() {
    var secret;               // Local to myFunction()
    secret = "Hello, world!"; // Only local secret variable changed
    console.log(secret);      // "Hello, world!"
}

console.log(secret);          // "Global"

Dropping the var will only make it global if the variable has already been defined in the global scope:

var secret = "Global";        // Global variable declaration

function myFunction() {
    secret = "Hello, world!"; // Global secret variable changed
    console.log(secret);      // "Hello, world!"
}

console.log(secret);          // "Hello, world!"
James Donnelly
  • 126,410
  • 34
  • 208
  • 218