Yeah, thx, for examples and explanations, I know about this stuff (and
the reasons 'caused this struff).
In JS, I could prefix the method name with an underscore, but that's justan
unenforcable convention
btw, to keep in mind that "that's not allowed" - is often the most
useful encapsulation; but, sure, *syntactic sugar* as private,
protected, public - is useful features (that's why there where
suggested).
But encapsulation itself is not related to private and protected: e.g.
it could be simple function which *encapsulates* (please, pay
attention, that i don't use *hides* word) some complex calculations
making usage of it - *abstract* (yeah, for user it can be not so
important *how* this function (e.g Math.round(...)) is written, he/she
just uses it).
Now checkSlices() is accessible to any user of my Sandwich. I'd rather
hide it, because I may want to change it later
Yes, sure, but saying that, you again think about encapsulation in
"security" reason, afraid that some can change something that you
don't wanna be changed. If someone wants to change encapsulating data
- he will do it. Just opens your source code and make this method
public. The reason is - user needs it. More than, as you know, such
"encapsulated vars" is not 100% hidden - using eval in some
implementation (e.g SpiderMonkey up to 1.7) we can pass calling
context to evaluate and get the needed variable object in needed scope
chain:
function A() {
var _a;
function _getA() {
return a;
}
return {
getA: _getA
};
}
var x = new A;
print(x.getA()); // 10
eval('_a = 100', x.getA); // as "_a" in [[Scope]] of x.getA
print(x.getA()); // 100
and _checkSlices() would still be visible on each sandwich.
Here's a good example how encapsulation is made in Python: there
__private and _protected fields are made by this underscore name
convention and are not accessible from the outside. But from the other
hand, Python just renames such fields to _ClassName__privateField -
and by this name, this property is already accessible from the
outside. The reason? Again, programmer (doesn't matter who - author or
user) wants by himself to get encapsulated data. And if will be some
errors after that - responsible for that is fully programmer, but not
"damn! someone again changed my field
" or "what a typo!".
class A(object):
def __init__(self):
self.__a = 10 # private
def get_a(self):
return self.__a
a = A() # instance
a.__a # error, __a is private
a.get_a() # 10, it's ok
a._A__a # renamed private which is public now, also 10
Or in Ruby - from one hand there private and protected, but from the
other hand - there're also
methods .instance_variable_get, .instance_variable_set, .send, and so
on, which allow access to encapsulated data. The reason again?
Programmer or user doesn't afraid that someone will do directly with
his data, he just wants to get that data in a program by some needed
reason.
But sure, common simple interface to the outside - is a good solution,
and private and public sugar is useful *sugar* in some OOP-
realizations. I wanted to say about exactly JS, that there's now big
need to make that own methods in constructor for that. Encapsulation
should be treated as *abstraction helper* which helps to build systems
more clear. And if there's no this *sugar* as private and protected,
keeping in mind that "that's not allowed" and maybe using some naming
conventions as underscore - is quite good encapsulation. At least,
you'll not eat much memory.
Or I could use a closure to store the private information:
Or in your example, just use wrapped context when creating prototype -
in any case checkSlices method is common:
function Sandwich () {
this.upperSlice = Bread.getSlice();
this.lowerSlice = Bread.getSlice();
}
Sandwich.prototype = (function () {
// initialization context
function checkSlices () {
if (this.upperSlice.size != this.lowerSlice.size) {
throw new BreadException();
}
}
function bite () {
checkSlices();
// reduce sandwich size
}
checkSlices();
// prototype:
return {
constructor: Sandwich,
bite: bite
};
})();
var aSandwich = new Sandwich;
1000 objects will always need 1000 "slots"
I meant that 1000 objects will have in it's own properties always new
function but with identical code; sure, that useless in meaning of
memory usage.
For example, I would use it to implement a ticker or other widgets, but
I wouldn't use it to model points on a canvas or rows in a table.
Yeah, sure, your choice, i just wanted you to notice main
encapsulation principle, and do not think that if you put something
into private area, everything will be always OK from this moment.
Nope, if user will want to change it - he will - repeat, just will
open your source and change private to public. But if programmer is
_understands_ what he does - there's no big need *in JS* to eat so
much memory creating closured methods in constructor.
In other systems, where, again repeat, there's that *sugar* (private,
protected), sure it very useful, 'cause helps to build more *abstract*
systems.
/ds