S
Scott Sauyet
What techniques to people use to hide implementation details in shared
code, especially to keep helper variables reasonably private?
Several threads on FAQ questions had me randomly reading the FAQ, and
the entry on checking for an open child window [1] made me pause. The
suggestion not to use pop-ups is fine, and there is nothing exactly
wrong with the code. But it introduces a global variable as well as
the function. This might well be what's wanted here, but often it's
just unwanted clutter, and I'm wondering what suggestions the experts
here have to avoid such clutter.
For example, the following adds the unwanted global "count":
var count = 0;
function test() {
alert("#" + (++count) + " run at " + new Date());
}
There are several ways to deal with that. I often use a closure:
var test = (function() {
var count = 0;
return function() {
alert("#" + (++count) + " run at " + new Date());
}
})();
Or we could make "count" a property of the function:
function test() {
test.count = test.count || 0;
alert("#" + (++test.count) + " run at " + new Date());
}
I know that there are performance concerns having to do with the
overuse of closures, but I don't really know any details. Obviously
that is an argument against the first technique. Another argument
against it is the additional syntactic complexity.
But the closure technique also has the advantage that the
implementation doesn't leak at all, whereas in the other one, the
implementation is exposed and could be manipulated by malicious or
clueless use, via, say:
test.count = 42;
Obviously, in many situations that is simply not an issue. ("Doc, it
hurts when I do *this*." "So don't do that!") But when writing
reusable code for a wide user base, it might be at least one
consideration.
There are also OO techniques to handle this such as this:
function Thingy() {
this.count = 0;
}
Thingy.prototype.test = function() {
alert("#" + (++test.count) + " run at " + new Date());
}
var thingy = new Thingy();
But this is no longer a drop-in replacement for the original function,
and it requires the object "thingy" in the global scope. And
sometimes, there's the stupid problem of simply not having a good noun
(hence "Thingy"); this can actually be an important consideration to
me. In general, unless I'm already coding all my relevant script in
an OO manner, this holds little appeal. Are there others for whom
this is obviously the best solution?
So how do you choose between these methods, or what other techniques
do you use to keep your implementation details hidden and especially
keep helper variables out of the global scope?
-- Scott
______________________
[1] Section 9.4 <http://jibbering.com/faq/#isWindowOpen>
code, especially to keep helper variables reasonably private?
Several threads on FAQ questions had me randomly reading the FAQ, and
the entry on checking for an open child window [1] made me pause. The
suggestion not to use pop-ups is fine, and there is nothing exactly
wrong with the code. But it introduces a global variable as well as
the function. This might well be what's wanted here, but often it's
just unwanted clutter, and I'm wondering what suggestions the experts
here have to avoid such clutter.
For example, the following adds the unwanted global "count":
var count = 0;
function test() {
alert("#" + (++count) + " run at " + new Date());
}
There are several ways to deal with that. I often use a closure:
var test = (function() {
var count = 0;
return function() {
alert("#" + (++count) + " run at " + new Date());
}
})();
Or we could make "count" a property of the function:
function test() {
test.count = test.count || 0;
alert("#" + (++test.count) + " run at " + new Date());
}
I know that there are performance concerns having to do with the
overuse of closures, but I don't really know any details. Obviously
that is an argument against the first technique. Another argument
against it is the additional syntactic complexity.
But the closure technique also has the advantage that the
implementation doesn't leak at all, whereas in the other one, the
implementation is exposed and could be manipulated by malicious or
clueless use, via, say:
test.count = 42;
Obviously, in many situations that is simply not an issue. ("Doc, it
hurts when I do *this*." "So don't do that!") But when writing
reusable code for a wide user base, it might be at least one
consideration.
There are also OO techniques to handle this such as this:
function Thingy() {
this.count = 0;
}
Thingy.prototype.test = function() {
alert("#" + (++test.count) + " run at " + new Date());
}
var thingy = new Thingy();
But this is no longer a drop-in replacement for the original function,
and it requires the object "thingy" in the global scope. And
sometimes, there's the stupid problem of simply not having a good noun
(hence "Thingy"); this can actually be an important consideration to
me. In general, unless I'm already coding all my relevant script in
an OO manner, this holds little appeal. Are there others for whom
this is obviously the best solution?
So how do you choose between these methods, or what other techniques
do you use to keep your implementation details hidden and especially
keep helper variables out of the global scope?
-- Scott
______________________
[1] Section 9.4 <http://jibbering.com/faq/#isWindowOpen>