Reputation: 523
When adding a new function to a prototype like this you don't have access to variables defined in the constructor function because they are out of scope.
function Thing() {
var something = 357;
}
Thing.prototype.doSomething = function () {
// no access to something because it is out of scope
console.log(something);
};
Thanks to closures when adding the function to the prototype within the constructor function it has access to variables defined there.
function Thing() {
var something = 357;
Thing.prototype.doSomething = function () {
console.log(something);
};
}
Is this an okay way to get access to those variables or is there any better pattern to achieve the same goal? Are there any pitfalls I have to look out for?
Upvotes: 2
Views: 712
Reputation: 43718
There's some fatal flaws with your design:
Redefining functions each time the constructor is called is unavoidable with privileged functions, but if you choose to go down that path, you would define the functions directly on this
rather than the prototype.
function SomeObject() {
var privateVar = 'private value';
this.somePriviledgedFunction = function () {
//Use privateVar here
};
}
Now, with the support of WeakMap
, there's a new pattern that would let you access private members from functions defined on the prototype. You would basically use an IIFE around your class declaration and have a shared WeakMap
only visible within that scope to hold all private members. Object instances will be used as keys so that their values gets garbage collected when the objects are no longer around.
var SomeObject = (function (privates) {
function SomeObject(someValue) {
privates.set(this, {}); //initialze the privates scope
privates.get(this).privateVar = someValue;
}
Object.defineProperty(SomeObject.prototype, 'privateVar', {
get: function () {
return privates.get(this).privateVar;
}
});
return SomeObject;
})(new WeakMap());
var o1 = new SomeObject('first object');
var o2 = new SomeObject('second object');
o1.privateVar; //first object
o2.privateVar; //second object
However, note that every SomeObject
's prototype functions that need access to private variables will have to be defined within the same module (within the surrounding IIFE). Another issue would be that other instances of a class could potentially steal other's privates if one is not careful with the design, but not from any function defined outside the IIFE, so that's no a real issue to me.
Upvotes: 1
Reputation:
You won't be able to access a private variable from the prototype. You can, however, access public variables. I have found that this is a good tradeoff:
function Thing() {
this._something = 357;
}
Thing.prototype.doSomething = function () {
console.log(this._something);
};
The naming convention of placing a _
before a property is just an informal way of marking it as private, even though it actually isn't.
Upvotes: 2