wjhyfw
Last Updated: February 25, 2016
·
3.414K
· boopathi
Cover

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.

Say Thanks
Respond

5 Responses
Add your response

2305
309686 10150358450866411 5102478 n small

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 ·
2320
D42a7264714dee5006b9c99d2567a320

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 ·
2321
D42a7264714dee5006b9c99d2567a320

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 ·
2323
Cover

@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 ·
2324
D42a7264714dee5006b9c99d2567a320

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 ·