Last Updated: February 25, 2016
·
3.941K
· boopathi

Prototypes can't talk to local variables in the constructor

var counter = function () {
  var count = 0;
  this.increment = function () { count++; }
  this.get = function() { return count; }
}
//now 
counter.prototype.decrement = function () {
   count--; //will be undefined :)
}

Well, this might not seem weird unless you compare it with some other programming language where Object Orientation is proper and true.

class counter {
private: int count;
public: 
  void increment() { count++; }
  void decrement();
}
void counter::decrement { count--; } //count is not undefined.

JavaScript is not a queer creature. There is no actual OOP in the language. The scope is what that helps us in simulating Object Orientation.

5 Responses
Add your response

True, but is there a reason why you wouldn't make count a property of the object? Or maybe the title of this pro-tip should be "Use closures to protect local variables from methods in the prototype chain"? Kidding.

For the sake of your example, it would be nice to see you instantiate counter() as myCount and call myCount.decrement() to show where the undefined error will occur in the order of execution. Then, changing var counter to this.counter would fix the rest. Or, conversely, show how your get() method could be used in decrement().

over 1 year ago ·

Your examples are not equivalent.

In the JavaScript code sample you define a local variable inside the constructor function. Although you omitted the constructor definition in your C++/Java example, it's still there implicitly and if you did define it and had some local variables inside, their scope would be limited to the constructor.

Instead you define a member variable for the class in your second example. Now to start with, there is no such thing as class in JavaScript and hence no such thing as class methods and class properties. However the prototype system (which, I stress again, is not the same as class system in OOP languages) and the ability to dynamically alter function execution context in JavaScript provide you with a powerful mechanism to write your program, you should just turn your way of thinking a little bit and perhaps learn more about how functions and prototypes work in js.

Note that the above said doesn't mean that you can't use the principles of OOP with JavaScript. It is possible, just keep in mind that certain aspects won't be enforced by the language itself and instead provided as a syntactic sugar. The ExtJS framework has a pretty decent class system, just take a look at this source code example:
http://docs.sencha.com/ext-js/4-0/source/Basic.html#Ext-form-Basic

over 1 year ago ·

Worth adding "the working version" of your javascript example:

var counter = function () {
  this.count = 0;
  this.increment = function () { count++; }
  this.get = function() { return count; }
}
//now 
counter.prototype.decrement = function () {
   this.count--; // yes, you have to use `this` in javascript a lot!
}

// using the "class"
c = new counter();
c.decrement();
console.log(c.count);    // -1
over 1 year ago ·

@dpashkevich The point of this post is "Prototypes can't talk to local variables in constructor".

this.count = 0;

is a pretty good method to follow, but the stress is, when we distribute the code to beginners, some might end up writing code that messes up the sensitive information simply by extending the code via prototypes (or) directly modifying count in this case. So we might want to simulate a model where we can use something as private variables. (stressing - by private, I don't mean typical class System as in other languages.)

The point again, is just, if we write JS code assuming that to represent a class (simulating it), then, there is a bottleneck of not accessing some variables - destined to contain secure information that should be modified based on some function alone and should not be accessed directly.

over 1 year ago ·

Ok after re-reading the title of your post for the n-th time, I figured what's your main point of frustration is.

Yes, that doesn't happen in JavaScript. You can create local variables via a closure but then you'd have problems with inheritance.

The bottom line is that you shouldn't enforce private variables like that in JavaScript, just make everything a property of your object and enjoy the benefits of inspecting/debugging the objects. This may be a concern in environments like NodeJS but I don't see how it can be critical in a browser webapp.

over 1 year ago ·