简体   繁体   中英

What's the reason of the following JavaScript syntax when using closures?

Studying about closures, I looked at the Developer's Mozilla article about it and saw the code below:

var counter = (function() {
  var privateCounter = 0;
  function changeBy(val) {
    privateCounter += val;
  }

  return {
    increment: function() {
      changeBy(1);
    },

    decrement: function() {
      changeBy(-1);
    },

    value: function() {
      return privateCounter;
    }
  };
})();

console.log(counter.value());  // 0.

counter.increment();
counter.increment();
console.log(counter.value());  // 2.

counter.decrement();
console.log(counter.value());  // 1.

I'm confused about how the function is attributed to the variable counter , because the function is initially envolved by those parentheses, and after all, there are also two unreaseble parentheses together... I just wondered, what's the reason of that syntax? I certainly would do:

var counter = function() {
  var privateCounter = 0;
  function changeBy(val) {
    privateCounter += val;
  }

  return {
    increment: function() {
      changeBy(1);
    },

    decrement: function() {
      changeBy(-1);
    },

    value: function() {
      return privateCounter;
    }
  };
};

But then I got the error

Uncaught TypeError: counter.value is not a function

When I do console.log(counter.value());

Can someone please explain it to me?

What you're looking at is an Immediately Invoked Function Expression or IIFE. This code is creating a function, then immediately calling that function, then assigning the return value of the function to counter . So counter isn't a function, it's an object with three properties: increment , decrement , and value .

The reason that they used an IIFE was to make what's essentially a private variable. privateCounter is only in scope to other code inside that function, which means only increment , decrement , and value can access it.

If they didn't care about making the variable private, the equivalent code would be:

var publicCounter = 0;
function changeBy(val) {
  publicCounter += val;
}

var counter = {
  increment: function() {
    changeBy(1);
  },
  decrement: function() {
    changeBy(-1);
  },
  value: function() {
    return publicCounter;
  }
}

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