I am trying to simulate a simple Holder "class" in JavaScript with a "private" property that holds something and "public" getter and setter "methods" to access the value.
The approach exhibited by HolderA
below is mentioned e.g. here. The other approach I more or less arrived at by mutation but I guess it must be recognizable as an idiom as well. I like it because it contains no this
or prototype
stuff and seems very elementary and functional. Is there a difference between the two?
The test code (I run it under nodejs
) seems to suggest that the two approaches are identical except that in the first case the objects I get have typeof
object
whereas in the second function
.
var test = function(o) {
var initialValueCorrect = (!(typeof o.getX()==='undefined'))&&(o.getX()===0);
var VALUE_TO_SET = 10;
o.setX(VALUE_TO_SET);
var getSetWorks = o.getX()===VALUE_TO_SET;
var xIsPrivate = (typeof o.x === 'undefined');
var xHasCorrectValue;
if (!xIsPrivate)
xHasCorrectValue = o.x === VALUE_TO_SET;
return {initialValueCorrect: initialValueCorrect,
getSetWorks : getSetWorks,
xIsPrivate: xIsPrivate,
xHasCorrectValue: xHasCorrectValue};
};
var HolderA = (function() {
function foo(x) {
this.getX = function() {
return x;
};
this.setX = function(_x) {
x = _x;
};
};
return foo;
})();
var createHolderB = (function() {
var x;
function foo(_x) {
x = _x;
return foo;
}
foo.getX = function() {
return x;
};
foo.setX = function(_x) {
x = _x;
};
return foo;
})();
var objects = [{object: new HolderA(0), name: "approach with constructor-invocation and 'this'"},
{object: createHolderB(0), name: "approach with normal function invocation and closed variable"}];
for (var i = 0; i<objects.length ; i++) {
var testResult = test(objects[i].object);
console.log('['+objects[i].name+']: the object is a: '+(typeof objects[i].object)
+'\n\n\t\t\t'+JSON.stringify(testResult)+'\n\n\n\n\n');
}
update
As Bergi
has pointed out function createHolderB
in my code above is plain wrong and only creates a singleton object. So, is not really a "constructor" function. To that end I've now created createHolderC
which can be used to really create multiple objects with a hidden private property like this:
var objectC1 = createHolderC()(0);
Now, is there any material difference between HolderA
and the createHolderC
function or is the difference purely stylistic?
var createHolderC = function () {
return (function() {
var x;
function foo(_x) {
x = _x;
return foo;
};
foo.getX = function() {
return x;
};
foo.setX = function(_x) {
x = _x;
};
return foo;
})();
};