0

function Peon(number) {
  this.number = number;

  this.inc = function() {
    number = number + 1;
  };

  return true;
}
var p = new Peon(10);

function returnNumber() {
  p.inc();
  alert(p.number);
}
<input id="b00" type="button" value="Click" onclick="returnNumber()">

This code doesn't work as intended. Is there a way to make it work without having to write

this.number=this.number+1;

Here it is a trivial choice, but in bigger codes not having this.* would make it a lot more readable. Is it possible?

5 Answers 5

3

You can make number "private", but then you need a getter:

function Peon(number) {
  var number = number;

  // increment
  this.inc = function() {
    number++;
  };

  // a simple getter
  this.getNumber = function() {
    return number;
  }
}

var p = new Peon(10);

function returnNumber() {
  p.inc();
  alert(p.getNumber());
}
<input id="b00" type="button" value="Click" onclick="returnNumber()">

You should read Douglas Crockfords "The Good Parts" for more information on how to use this pattern, there's (limited) a preview available at Google Books.

Also you don't need to return something from the constructor, your return true is superfluous.

Sign up to request clarification or add additional context in comments.

2 Comments

You can read about Crockford's private members pattern on his website: javascript.crockford.com/private.html It's very important to note that if you're going to have a lot of Peons, this private member pattern consumes markedly more memory than just using a property, because each individual object will have its own copy of both functions defined within the constructor. They are not, and cannot be, shared between objects. So the tradeoff is privacy v. memory use. Memory consumption is a major problem on IE and Firefox. If you're only going to have a few Peons, it doesn't matter.
return true is indeed superfluous and essentially ignored at the end of a constructor, but returning an object rather than a primitive would not be ignored and would return that object rather than the new Peon object.
1

No, you have to use this to reference properties on the this object. Note that this in JavaScript is very different from this in some other languages, like C or Java. More here and here.

What your code is doing is accessing the number argument that was passed into the Peon constructor function, rather than the this.number property you created in the constructor. Which is why it doesn't work as intended, but doesn't fail, either.

There's no reason to define your inc operation within the Peon constructor function, BTW, and some good reasons not to (every individual object created via Peon will get its very own copy of that function). So instead, you can define it like this:

function Peon(number) {
    this.number = number;
  
    // Don't return values out of constructor functions, it's
    // an advanced thing to do. In your case, you were returning
    // `true` which was being completely ignored by the JavaScript
    // engine because it's not an object. If you had returned an
    // object, the `this` object created for the `new Peon()` call
    // would have been thrown away and the object you returned
    // used instead.
}

Peon.prototype.inc = function() {
    ++this.number;
};

var p = new Peon(10);

function returnNumber() {
    p.inc();
    console.log(p.number); // shows 11, then 12, etc.
}
<input id="b00" type="button" value="Click" onclick="returnNumber()">

Or using modern JavaScript features (ES2015+):

class Peon {
    constructor(number) {
        this.number = number;
    }
    
    inc() {
        ++this.number;
    }
}

const p = new Peon(10);

function returnNumber() {
    p.inc();
    console.log(p.number); // shows 11, then 12, etc.
}
<input id="b00" type="button" value="Click" onclick="returnNumber()">

3 Comments

+1 to both you and @Ivo. The combination of the two makes for a great answer overall.
as a side note - why ++this.number instead of this.number++? I know they evaluate slightly differently, but in this use case would be interchangeable. Just curious since I tend to see the this.number++ form more frequently.
@Matt: My native language is English, in which "verb-noun" is a dramatically more common speech pattern than "noun-verb", and so I write "increment x" (++x) rather than "x increment" (x++). If I were a native German speaker, I suspect I'd write x++. :-) In the vast majority of cases, there's no real-world difference. (I emphasize "real-world" because otherwise lurkers will pounce and try to micro-optimize. :-) )
0

Not really, but this is a little more concise

this.number++

Actually, as a side note, you'd be better off declaring .inc outside the constructor of Peon. You could do this with prototype. That way the inc function is not reconstructed each time you create an object of type Peon.

Peon.prototype.inc = function(){
    this.number++;
}

Or instead of using p.inc() you could do p.number++. That's the only way I can think of avoiding the this keyword.

Comments

0

The only readable way I can see doing it would be:

this.inc = function() {
   this.number++;
};

Otherwise, in your "bigger codes" postulation, you could do something like this:

this.inc = function() {
   var number = this.number; // obviously simple here.  Imagine more complexity
   number++;
};

Comments

0

Yes, you do not need to use 'this' in javascript. You can access variables via closure instead of 'this'

function createPeon(number) {

  function inc() {
    number = number + 1;
  };

  function getNumber() {
    return number;
  }

  return {
    inc,
    getNumber
  };
}
var p = createPeon(10);

function returnNumber() {
  p.inc();
  alert(p.getNumber());
}
<input id="b00" type="button" value="Click" onclick="returnNumber()">

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.