2

In the following code, why are both of the methods (increment and print) listed inside of return? Why can't you just use return counter++? Also, what does it mean to return a console.log?

function create() {
  var counter = 0;
  return {
    increment: function() {
      counter++;
    },
    print: function() {
      console.log(counter);
    }
  }
}

Thanks!

Paul D. Waite
  • 96,640
  • 56
  • 199
  • 270
djs22
  • 1,148
  • 3
  • 14
  • 30
  • The code would be more readable with the missing semi-colon – Šime Vidas Dec 26 '10 at 01:42
  • @Šime Vidas This code would be just as readable with no semi-colons, if it remains formatted nicely over lines (as it is now) :-) (And it would be as un-readable with semi-colons if it was messy and scrunched up...) –  Dec 26 '10 at 01:53
  • You *could* use `return counter++`, imagine: `x = create(); console.log(x.increment())`. However, the first value will be 0 because the ++ "happens-after" the current value of the variable is evaluated in the expression. –  Dec 26 '10 at 01:58
  • @pst I disagree. My remark is a tiny detail, but it still would make a difference regarding readability. The second ending brace would be followed by a semi-colon - `};` - and that would indicate that a statement ends at that point in code. This additional piece of information makes it more readable. – Šime Vidas Dec 26 '10 at 01:59
  • @Šime Vidas It adds no "improvement" for me above the acceptably clean indentation levels. –  Dec 26 '10 at 05:01

5 Answers5

5

What this returns is more or less a Counter, if we rename the topmost function, it should make more sense.

Well what does it do? Let's add some comments

function Counter() { // a function, nothing special here
  var counter = 0; // a variable that's local to the function Counter
  return { // return an object literal {}
    // which has a property named 'increment'
    increment: function() { // that's a function AND a closure
      counter++; // and therefore still has access to the variable 'counter' inside of Counter
    },
    print: function() { // another function
      console.log(counter); // this logs to the console in most web browser
                            // the console object was introduces by Firebug 
                            // and effort is made being to standardize it
    }
  }
}

Example usage:

var a = Counter(); // you don't need the new keyword here sinc in this case
                   // there's no difference because the implicit return overwrites
                   // the normal constructor behavior of returning 'this'
a.increment();
a.print(); // 1
var b = Counter();
b.print(); // 0

Note the variable counter inside the function is not accessible from the outside, therefore it's readonly, an effect you can only achieve by using a closure.

Community
  • 1
  • 1
Ivo Wetzel
  • 46,459
  • 16
  • 98
  • 112
4

This code returns an object that contains two methods.

It uses a feature called an object literal:

var sampleObject = { someProperty: 3, otherProperty: "Hi there!" };

In this case, the properties are function literals.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
3

The create function returns an object that contains two methods - increment and print.

Every time you call the create function, a new object will be returned. This means that you can have multiple "counters" at the same time.

var counter1 = create();
var counter2 = create();

counter1.increment();
counter1.print(); // prints 1

counter2.print(); // prints 0

Btw, the local variable counter of the create function is bound to the increment and print methods through a closure. Read about closures here: http://jibbering.com/faq/notes/closures/

Paul D. Waite
  • 96,640
  • 56
  • 199
  • 270
Šime Vidas
  • 182,163
  • 62
  • 281
  • 385
1

The code you suggest:

function create() {
  var counter = 0;
  return counter++;
}

would have a different effect. That would return 0, then increment counter (which would then go out of scope).

The actual code returns a object (created with a object literal, as noted by SLaks). The object has two methods, increment and print. The increment method increments counter (it does not return it). print prints it using console.log.

The reason this works is that counter is closed into both methods of the object literal. This roughly means it stays alive, and is added to those methods' scopes. Closures are a commonly used and important feature of JavaScript.

Matthew Flaschen
  • 278,309
  • 50
  • 514
  • 539
0

The increment operator ++ when following a return would essentially be working retroactively. So if your variable value was 5 and you return it following by ++, you would return 5.

console.log() is typically used to debug things. It outputs the value of counter in this case to the console.