Protected static members, abstract classes, object composition vs. subclassing

K

Kevin Prichard

Hi all,

I've recently been following the object-oriented techiques discussed
here and have been testing them for use in a web application. There is
problem that I'd like to discuss with you experts.

I would like to produce Javascript classes that can be "subclassed"
with certain behaviors defined at subclass time. There are plenty of
ways to do this through prototyping and other techniques, but these
behaviors need to be static and protected. By protected this means
that they can be overridden (or reassigned) in subclasses, and
privileged subclass methods can access them, but callers external to
the class cannot.

I've been attempting to define a factory function that transfers its
parameters to an anonymous object while defining the constructor in a
-with- block. (This is what I'm loosely referring to as "subclassing"
- it's really object composition.) This works, but not for
externally-defined functions. They can't see the protected static
members.

// helper functions to be passed into factory function, for protected
static use
var ProtStaticMethod1 = function(that) { // caller passes in 'this'
// call privileged bridge function to access protected static value
alert("PSM1: "+that.GetPSField());
};

var ProtStaticMethod2 = function(that) {
alert("PSM2: "+ProtStaticField);
};

// helper function, to be accessed as a privileged class method
var candidateStaticMethod = function() {
alert("PrivOutsiderSM: "+
(typeof(ProtStaticField)=="undefined" ?
"Outsider static method can't find ProtStaticField" : ProtStaticField)
);
};

// factory function; params: 1) function, 2) any data
var BaseFactory = function(psmMethod,psmField,privilegedMeth) {
with ({
ProtStaticField : psmField,
ProtStaticMethod : psmMethod
})
{
function Constructor() { // instance members just for fun
var privInstMember = "privateMember";
function privInstMethod() { alert(privInstMember); };
};
Constructor.prototype.ShowPSField = function() {
alert("ShowPSField: "+ProtStaticField); }
Constructor.prototype.InvokePSMethod = function() {
ProtStaticMethod(this); }
Constructor.prototype.SetPSField = function(val) {
ProtStaticField=val; }
Constructor.prototype.GetPSField = function() { return
ProtStaticField; }
Constructor.PrivOutsideMethod = privilegedMeth;
Constructor.PrivInsideMethod = function() {
alert("PrivInsiderSM: "+
(typeof(ProtStaticField)=="undefined" ?
"Can't find ProtStaticField" : ProtStaticField) );
};
};
return Constructor;
};
SubClass1 = BaseFactory( ProtStaticMethod1, "ProtStaticField_Class1",
candidateStaticMethod );
// can a function defined outide the constructor's scope see privileged
static fields?
SubClass1.PrivOutsideMethod();

SubClass2 = BaseFactory( ProtStaticMethod2, "ProtStaticField_Class2",
candidateStaticMethod );
// can a privileged static constructor method see protected static
fields?
SubClass1.PrivInsideMethod();

obj1 = new SubClass1();
obj2 = new SubClass2();
obj1.ShowPSField(); // should display "ProtStaticField_Class1"
obj2.ShowPSField(); // should display "ProtStaticField_Class2"
obj1.InvokePSMethod(); // should display "ProtStaticField_Class1"
obj2.InvokePSMethod(); // CRASH - ProtStaticMethod2 can't see
ProtStaticField


This has worked for producing subclasses whose protected static fields
are composed of just about any values.

BUT, my chief complaint is that functions defined outside the scope of
the factory's -with- block aren't able to see the protected static
members. Is that just a limitation of this technique, or is there
something I need to change? The only thing that has worked at all is,
as you can see, to add privileged bridge functions to the constructor's
prototype. These act as a go-between for the externally defined
functions stored, e.g. GetPSField as accessed by external function
ProtStaticMethod1.

Is there a better approach for producing "subclasses" whose protected
static methods can be varied from outside, yet still access protected
members?

Thanks in advance for any feedback,

Kevin Prichard
 
V

VK

Kevin said:
Hi all,

I've recently been following the object-oriented techiques discussed
here and have been testing them for use in a web application. There is
problem that I'd like to discuss with you experts.

<snip>

Wow - you really tried to get 100% out of JavaScript object model :)

You may also want to look at my game records:

<html>
<head>
<title>TMP</title>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<script type="text/javascript">

/**
* myClassSuper is used as super class of myClass
*/
function myClassSuper() {
// Adds protected member <messenger>
// from myClassUtils class:
this.messenger = function(message) {
this.utils.messenger(message);
}
}

/**
* Protected class myClassUtils
* can be used only from within
* myClass:
*/
function myClassUtils(obj) {

if (myClassUtils.caller !== myClass) {
throw new Error("Get out of my protected stuff!");
}

this.messenger = function(message) {
// JavaScript has a very weak feeling
// of the context in objects. I would call
// it "incontinence of <this>" :)
// Any way:
// alert(arguments.callee.caller);
// gives you the public method of myClassSuper
// - you may check against somehow.
alert('myClassUtils.messenger says: '+message);
}

}


/**
* myClass constructor:
*/
function myClass() {
myClassSuper.call(this); // think super()
this.utils = new myClassUtils(this);
}

function init() {

try {
var goodBoy = new myClass();
goodBoy.messenger('Hi!');
}
catch(e) {
alert(e.message);
}

try {
var badBoy = new myClassUtils();
badBoy.messenger('Hi!');
}
catch(e) {
alert(e.message);
}
}
</script>
</head>

<body onload="init();">

</body>
</html>

Note [1]
I'm using the <class> term as a convenience term. You are free to call
it <prototype> or <constructor holder> or <foobar> or any other name.
;-)

Note [2]
JavaScript and Java are different languages but they have some things
in common. In the particular interpreted nature of JavaScript and
byte-coded (read: "interpreted") nature of Java makes them both open
source languages.
It means that protected/private/static/final stuff in them is not a
bulletproof lock but merely an "inconvenience protection" (like locking
context menu on the page). You always can study the code and/or spoof
the constructor. In JavaScript it's easier than in Java - that's the
only difference.
So if you want to satisfy your boss, show him how the call to
"protected" member leads to an exception. He should get happy. :)
And you personally should remember that it's all an imaginary
protection and you should never expose any sensitive data neither in
public nor in protected/private members.

I personally just ended up by naming all "protected" and "private"
members with $_ + name. And I said in comments that if something starts
with $_ then you should not touch it directly or the object may crash -
and from this point out I simply washed my hands. This approach may be
discutable but it saves hell a lot of time and space on
{pseudo {clo}sure {protection}} which doesn't guarantee anything anyway.
 
R

Richard Cornford

Kevin said:
I've recently been following the object-oriented techiques
discussed here and have been testing them for use in a web
application. There is problem that I'd like to discuss with
you experts.

This is such a massive subject that I am a little included to let it go.

Javascript is a dynamic language using prototype based inheritance for
OO behaviour in which there are no access modifiers and no classes (or
only one class, which is effectively the same thing). (Disregarding the
unpublished and unknown ECMA 262 4th edition, JScript.net and JavaScript
2, which are all irrelevant to client-side scripting and will remain so
for some considerable time to come).

The only Object type in javascript (the 'native ECMAScript object') is
an unordered collection of name-value pairs, to which named properties
can be added at runtime. So when an object can be considered to be or a
distinct 'class' that distinction represents that fact that it is an
instance of the one Object type that has been modified in a particular
way that is common to all instances of the same 'class' but distinct
from any processes that other 'classes' undergo.

So, given a function that is to act as a constructor:-

function MyObject(){
...
}

- and using the constructor with the new operator:-

var inst = new MyObject();

- the object instantiation process involves taking a new instance of the
native ECMAScript object and changing its internal [[Prototype]]
property from its default Null value to a reference to the object
referred to by - MyObject.prototype - (but only if it does refer to an
object), and then passing this native ECMAScript object to the execution
of the function body as the - this - object, and finally returning the
now modified native ECMAScript object (assuming that the execution of
the function body does not explicitly return another object). The
combination of a constructor function and its prototype define a process
that is applied to a native ECMAScript object that modifies it in a way
that allows the result to be considered as being of a distinct 'class'.

However, describing objects created in this was of being of a 'class' is
only a conceptual convenience. There always was only one Object type;
the mutable native ECMAScript object, and because javascript is dynamic
any object created as an instance of a 'class' is still open to run-time
modification and may be stripped of the characteristics that define its
''class' or transformed into what for all practical purposes may be an
instance of another 'class'.

Of course in an OO design it would be unusual for an object that was
conceptually of one 'class' to undergo runtime modification that
prevented it form qualifying as that 'class' (at least once the desired
'class' had been established, as the creation process may involve an
initial instantiation of one 'class' followed by a sequence of specific
additional modifications to create what will then be considered as being
another (possibly 'sub') 'class').

So, for convenience, the label 'class' can be attached to a category of
object that have undergone a 'like' sequence of modifications in their
creation, and are then not going to be subject to the types of run-time
modification that would break their 'likeness'.

This makes a 'class definition' the totality of code that applies these
modification to what starts out as a native ECMAScript object, provided
that code also does not undergo runtime modification that would change
the 'likeness' of the resulting objects.

Notice that this definition goes well beyond the combination of a
constructor function and the assignment of properties to its prototype.
Those are a long way short of being the only methods of crating object
instances that have the 'likeness' that allows then the be considered as
being of the same 'class'. (One of the reasons that javascript IDEs are
not nearly as helpful as they can be in class-based language; it is
difficult for software to see when the concept of 'class' is being
implemented in javascript, so they usually give up and only recognise
constructor/prototype combinations).

Javascript also has no access modifiers. It is, for example, difficult
to talk of a member being 'static' in a language that has no classes,
and the properties of any object that it itself accessible are
inevitably public.

However, if the concept of 'class' is appropriate for use in describing
javascript code it also becomes viable to talk of aspects of this code
in terms of access modifiers.

'Public instance member' may be appropriately applied to any property of
an instance of a 'class', as they will be visible and accessible to all
other code in the system.

'Public static member' is usually applied to properties of a 'classes'
constructor function, but may also apply to properties of an object that
provides a method that acts as a factory for instances of a 'class'. The
important aspect of 'static' is that it relates to a member that is 'of
the class' rather than of instances of that class.

Javascript needs no concept of 'public' because being public is what
object properties are by default. But having no concept of 'private'
might seem to preclude the possibility. However, it is in the nature of
javascript that it can emulate anything; trading the effort of writing
the emulation, and the overheads of executing it, for having a facility
that is not naturally a part of the language.

Rendering something 'private' is a matter of making it
inaccessible/invisible outside of a particular context. And because
javascript has closures, and closures allow code access to an
environment that is inaccessible/invisible outside of the closure,
javascript can emulate the concept of 'private'.

'Private instance members' may be created by having the constructor (or
factory) of an object form a closure, and the parameters, inner function
declarations and local variables are preserved in the closure in a way
that is inaccessible to code outside of the context of the constructor
(or factory). It is not possible to form a closure without making a
function object that was created within the context of a constructor (or
factory) accessible outside of that context. It is also not useful to
have 'private instance' members unless they can be interacted with by
instances of the 'class'.

The creation of the closure and the ability to access the 'private'
members is usually facilitated through the process of evaluating
function expressions within the context of the constructor (or factory)
and assigning the result as a method of the object instance. These
special methods of an object instance have been christened "Privileged"
methods, as they have the privilege of being able to interact with the
parameters, inner function declarations and local variables that
represent the 'private instance' members.

It is worth noting that this ability to access the 'private instance'
members of an object instance is a quality that belongs to the function
object that has been assigned as a method of the object instance, it is
not related to the fact that that function object is an method of the
object instance. This means that such a method may be hijacked and
assigned as a method of a different object, or executed as a function,
and will still have access to the 'private instance' members of the
object instance.

'Private static members' may be created by forming a closure with the
constructor and/or the methods of the constructor's prototype. This
involves creating the constructor and/or the methods of the prototype
within another function, and it is the parameters, inner function
declarations and local variables of that function that can be accessed
by any code within that function but not outside of it, and so become
the private static members. Accessible to all instances of that class
but invisible to other code.

Again it is the functions (including constructors) defined within the
outermost function that have access to these 'private static' members,
independently of their association with any objects.
I would like to produce Javascript classes that can be "subclassed"
with certain behaviors defined at subclass time. There are plenty of
ways to do this through prototyping and other techniques, but these
behaviors need to be static and protected. By protected this means
that they can be overridden (or reassigned) in subclasses, and
privileged subclass methods can access them, but callers external to
the class cannot.

O.k. That is a definition of protected that is dissimilar to any I have
considered. Are you trying to subclass dynamically, based upon runtime
conditions? Otherwise I am not sure I see any issue here.
I've been attempting to define a factory function that transfers its
parameters to an anonymous object while defining the constructor in a
-with- block. (This is what I'm loosely referring to as "subclassing"
- it's really object composition.) This works, but not for
externally-defined functions. They can't see the protected static
members.

If an externally defined function has access to the protected member in
what sense would it b protected?
// helper functions to be passed into factory function, for protected
static use
var ProtStaticMethod1 = function(that) { // caller passes in 'this'
// call privileged bridge function to access protected static value
alert("PSM1: "+that.GetPSField());
};

var ProtStaticMethod2 = function(that) {
alert("PSM2: "+ProtStaticField);
};

There is no object on the scope chain of this function with the name
'ProtStaticField' so the Identifier cannot be resolved. The scope chain
of all function objects is defined and fixed at the point of creation of
the function object, depending on the context in which that function
object is created. You cannot add or remove objects from the scope chain
once it has been created (though it is possible to add remove and modify
the properties of objects on the scope chain so long as you have a
reference to it.)
// helper function, to be accessed as a privileged class method
var candidateStaticMethod = function() {
alert("PrivOutsiderSM: "+
(typeof(ProtStaticField)=="undefined" ?
"Outsider static method can't find ProtStaticField" : ProtStaticField)
);
};

Similarly 'ProtStaticField' is not a named property of any object on
this function's scope chain.
// factory function; params: 1) function, 2) any data
var BaseFactory = function(psmMethod,psmField,privilegedMeth) {

There is no reason for this to be a function expression.
with ({
ProtStaticField : psmField,
ProtStaticMethod : psmMethod
})

If the - psmField - formal parameter was re-named to 'ProtStaticField'
and the - psmMethod - parameter re-named to - ProtStaticMethod - the
Activation/Valriable object for this execution context could take the
palace of the object within the - with - statement, and the - with -
statement could be avoided.
{
function Constructor() { // instance members just for fun
var privInstMember = "privateMember";
function privInstMethod() { alert(privInstMember); };
};

Strictly this is a syntax error as a FunctionDeclaration may not appear
in a Block statement. Browser environments mostly put up with this
error, but behave differently. IE and Opera will create the constructor
function outside of the - with - statement, while JavaScript(tm)
environments will create the function object inside the - with -
statement. Only a FunctionExpression should be allowed inside a Block
statements so that would be the sensible way of creating the constructor
inside a - with - statement. However, as the - with - statement is
serving no useful purpose here FunctionDeclaration for the constructor
could be retained by omitting the - with - statement, as then it would
be outside of the Block statement.

The result would resemble:-

function BaseFactory(ProtStaticMethod,ProtStaticField,privilegedMeth){
function Constructor() {
var privInstMember = "privateMember";
function privInstMethod() {
alert(privInstMember);
};
};
Constructor.prototype.ShowPSField = function() {
alert("ShowPSField: " + ProtStaticField);
};
Constructor.prototype.InvokePSMethod = function() {
ProtStaticMethod(this);
};
Constructor.prototype.SetPSField = function(val) {
ProtStaticField = val;
};
Constructor.prototype.GetPSField = function() {
returnProtStaticField;
};
Constructor.PrivOutsideMethod = privilegedMeth;
Constructor.PrivInsideMethod = function() {
alert("PrivInsiderSM: "+
(typeof(ProtStaticField)=="undefined" ?
"Can't find ProtStaticField" : ProtStaticField) );
};
return Constructor;
}
Constructor.prototype.ShowPSField = function() {
alert("ShowPSField: "+ProtStaticField); }
Constructor.prototype.InvokePSMethod = function() {
ProtStaticMethod(this); }
Constructor.prototype.SetPSField = function(val) {
ProtStaticField=val; }
Constructor.prototype.GetPSField = function() { return
ProtStaticField; }
Constructor.PrivOutsideMethod = privilegedMeth;
Constructor.PrivInsideMethod = function() {
alert("PrivInsiderSM: "+
(typeof(ProtStaticField)=="undefined" ?
"Can't find ProtStaticField" : ProtStaticField) );
};
};
return Constructor;
};
SubClass1 = BaseFactory( ProtStaticMethod1, "ProtStaticField_Class1",
candidateStaticMethod );
// can a function defined outide the constructor's scope see
privileged static fields?
SubClass1.PrivOutsideMethod();

SubClass2 = BaseFactory( ProtStaticMethod2, "ProtStaticField_Class2",
candidateStaticMethod );
// can a privileged static constructor method see protected static
fields?
SubClass1.PrivInsideMethod();

obj1 = new SubClass1();
obj2 = new SubClass2();
obj1.ShowPSField(); // should display "ProtStaticField_Class1"
obj2.ShowPSField(); // should display "ProtStaticField_Class2"
obj1.InvokePSMethod(); // should display "ProtStaticField_Class1"
obj2.InvokePSMethod(); // CRASH - ProtStaticMethod2 can't see
^^^^^
Not a crash, a runtime error, they are very different things.
ProtStaticField


This has worked for producing subclasses whose protected static
fields are composed of just about any values.

BUT, my chief complaint is that functions defined outside the scope of
the factory's -with- block aren't able to see the protected static
members.

The implication of javascript's lexical scoping is that they would not.
Is that just a limitation of this technique, or is there
something I need to change?

It is a limitation of what this code is doing, but not necessarily a
limitation of javascript. The problem with the above code is that it
demonstrated how you are doing what you are doing, and so shows its
limitations, it does not explain why you are doing it so it is not
possible to judge whether the limitation shown applies to the real
problem. It is unlikely that it really does.
The only thing that has worked at all is,
as you can see, to add privileged bridge functions to the
constructor's prototype. These act as a go-between for the
externally defined functions stored, e.g. GetPSField as accessed by
external function ProtStaticMethod1.

One of the tings that I would question in the design is the use of these
externally defined functions, or at lest how 'external' they really need
to be.
Is there a better approach for producing "subclasses" whose
protected static methods can be varied from outside, yet still
access protected members?

Be clear about the what and why of 'varied from outside', and the
criteria for 'outside' and it may be possible to answer. When you are
working with the more advanced aspects of javascript OO what you are
really trying to do has an enormous impact upon what would qualify as
the best way of doing it.

Richard.
 
R

Richard Cornford

VK said:
Kevin Prichard wrote:
You may also want to look at my game records:

I cannot speak for anyone else but I did not want to see it, and would
rather never see it again.

/**
* Protected class myClassUtils
* can be used only from within
* myClass:
Bullshit!

*/
function myClassUtils(obj) {

if (myClassUtils.caller !== myClass) {
throw new Error("Get out of my protected stuff!");
}

The - caller - property of functions is a non-standard extension and so
its use needlessly renders this code non-functional on all but a limited
number of browsers (excluding, for example, Opera).

This code throws an exception at the point of calling this function.
While most concepts of 'protection' extend to the employment of objects
at runtime.
Note [1]
I'm using the <class> term as a convenience term. You are free to call
it <prototype> or <constructor holder> or <foobar> or any other name.
;-)

Note [2]
It means that protected/private/static/final stuff in them is
not a bulletproof lock but merely an "inconvenience protection"
(like locking context menu on the page). You always can study
the code and/or spoof the constructor. In JavaScript it's
easier than in Java - that's the only difference.

It is difficult to see how having had your limited understanding of
programming pointed out to you so often you still fail to see your
understanding as misconceived. Access modifiers have nothing to do with
rendering the contents of object members secret, they are about imposing
control over how object interact with each other, and particularly which
objects are allowed to interact with which object members and how they
interact with them.
So if you want to satisfy your boss, show him how the
call to "protected" member leads to an exception. He
should get happy. :)
<snip>

Until the next programmer comes along and shows him:-

try {
var goodBoy = new myClass();
goodBoy.messenger('Hi!');
}
catch(e) {
alert(e.message);
}

try {
goodBoy.messenger.call({utils:goodBoy.utils}, 'Hi xxx!');
goodBoy.utils.messenger('Hi yyy xxx!');
({messenger:goodBoy.utils.messenger}).messenger('Hi mmm xxx!');
}
catch(e) {
alert(e.message);
}

- and he sees that your notion of 'protected' means 'wide open'. It is
easy to execute these 'protected' methods with any arbitrary object as
their - this - object.

It may be beyond your comprehension but emulations of access modifiers
are available that do genuinely restrict access, so this hollow sham of
yours really doesn't deserve any consideration at all.

But still, you give us an insight into why you are not interested in
learning to be good at web development. You are actually in the business
of trying to impress people who don't know any better, and not really in
programming at all.

Richard.
 
V

VK

Richard said:
- and he sees that your notion of 'protected' means 'wide open'. It is
easy to execute these 'protected' methods with any arbitrary object as
their - this - object.


This is what I said:
<quot>
It means that protected/private/static/final stuff in them is not a
bulletproof lock but merely an "inconvenience protection" (like locking

context menu on the page). You always can study the code and/or spoof
the constructor.
</quot>

If you would spend some of your precious time to read it.

Your beloved closures' tricks is *another* way but *not any better*
way. The question is only how many startup level users may it stop from
spoofing constructor. I would say that your {cur{l}ed} way is more
cryptic but it's really a discussion whos code obfuscator is more
reliable (the real answer is: none of any).

Also:
try - catch - finally and throw are parts of JavaScript / JScript for
forever (by Internet time scale) and any modern browser supports it
including Opera 8.x

Prehistoric and beta models (Opera 6.x, Netscape 3.x, Netscape 6.x,
Safari 1.x etc) are not subject of my preoccupation in the mean of
"make it work". But the startup block in the script should let them die
peacefully. Nevertheless I'm not post each line of code here as a
turn-key solution with the startup block and roll-back pages.
 
V

VK

Richard said:
try {
var goodBoy = new myClass();
goodBoy.messenger('Hi!');
}
catch(e) {
alert(e.message);
}

try {
goodBoy.messenger.call({utils:goodBoy.utils}, 'Hi xxx!');
goodBoy.utils.messenger('Hi yyy xxx!');
({messenger:goodBoy.utils.messenger}).messenger('Hi mmm xxx!');
}
catch(e) {
alert(e.message);
}

Actually... having read you post once again I'm missing the point of
your exaltation.

myClassUtils constructor is minded to be "protected" - not "private".
These are all different categories (depending of course of the school).

For me "protected" means that I cannot obtain an instance of such class
independently but only as a part of a super-imposed class (myClass in
this case).

So I don't see how the use of goodBoy which is a legal instance of
myClass may prove anything in the concern of the "protected" status.

"private" means that a particular member is accessible only to the
privileged object members - in the most common case to public object
members. So in the listed case we want to make
myClass.utils.messenger() to be accessible only to members of myClass.
It is more tricky because despite argument.callee.caller gives us the
actual caller, we cannot simply ask to caller "Who's your master?"
because the caller has no clue itself at that time ("incontinence of
[this]") But you can check against some caller's feature to see if it's
a valid caller. I left the final solution open so the relevant block is
commented out. The first idea would be to use Java's object
id-stamping. Thus each new instance get's an unique ID and you stamp
all members which this ID:

this.foo = /*public*/ function() {};
this.foo.oID = newID;

this.bar = /*private*/ function() {};
this.bar.oID = newID;

and then later in bar:

if (arguments.callee.caller.oID = (arguments.callee.oID) {
// legal call
}
else {
throw new Error("Attempt to access private member out of the object
scope");
}

I'm not saying this is a final solution and in any case it still
doesn't guarantee a buletproof protection as I said in the original
post.
 
V

VK

VK said:
if (arguments.callee.caller.oID = (arguments.callee.oID) {
// legal call
}

Need to buy a new keyboard - keys are steeking. Of course:

if (arguments.callee.caller.oID == (arguments.callee.oID)
 
T

Thomas 'PointedEars' Lahn

VK said:
if (arguments.callee.caller.oID == (arguments.callee.oID)
^^^^^^
This is still not standards compliant. It is possible to be used in a
well-defined host environment where either JavaScript or JScript are
available, not on the Web. E.g. Opera 8.51 implements no such property.


PointedEars
 
R

Richard Cornford

VK said:
Actually... having read you post once again I'm missing the
point of your exaltation.

myClassUtils constructor is minded to be "protected" - not
"private". These are all different categories (depending of
course of the school).

Protected is public to some (selected) objects and private to others.
With different languages applying different criteria to deciding who can
see what, and when.

This will be good.
"protected" means that I cannot obtain an instance of such
class independently but only as a part of a super-imposed
class (myClass in this case).

So nothing related to the meaning of the term in any programming
language?
So I don't see how the use of goodBoy which is a legal
instance of myClass may prove anything in the concern
of the "protected" status.

Your protected method could be called with any object as its - this -
object. If the function were a getter it would get for any object, if a
setter it would set for any object, and if it acted it would act for any
object.
"private" means that a particular member is accessible only
to the privileged object members - in the most common case
to public object members. So in the listed case we want to
make myClass.utils.messenger() to be accessible only to members
of myClass.

Well, the object design is stupidly elaborated for no reason, but if you
insist.
It is more tricky because despite argument.callee.caller
gives us the actual caller,

Or not, in ECMAScript, where no - caller - property is defined.
we cannot simply ask to caller "Who's your master?"
because the caller has no clue itself at that time

As there may be no caller it could not be asked anything. But otherwise
this is incoherent.
("incontinence of [this]")

This is another manifestations of your general misconception of
javascript. The - this - keyword has well-defined and constantly
implemented meaning, your problems with it stem from your not
understanding javascript and nothing else.
But you can check against some caller's feature to see if
it's a valid caller. I left the final solution open so the
relevant block is commented out. The first idea would be to
use Java's object id-stamping. Thus each new instance get's
an unique ID and you stamp all members which this ID:

Unnecessary as objects have distinct identity that can be verified.
this.foo = /*public*/ function() {};
this.foo.oID = newID;

this.bar = /*private*/ function() {};
this.bar.oID = newID;

You silly sod. Verification with a shared secret, and then making the
secret a public property of the objects so that it is not secret at all.
What a waste of effort! If you cannot apply better analysis to the
problem than this you are wasting everyone's time commenting on the
subject at all (although that goes for the vast majority of your posts
anyway).
and then later in bar:

if (arguments.callee.caller.oID = (arguments.callee.oID) {
^ ^
An assignment operator instead of comparison and unbalanced parenthesise
making this a syntax error?
// legal call
}
else {
throw new Error("Attempt to access private member out of the object
scope");
}

OK. That is actually less effective than your first attempt (even if the
errors were corrected).
I'm not saying this is a final solution

I don't know, if your problem is only convincing people who don't know
any better this will do as well as the first.
and in any case it still doesn't guarantee a buletproof
protection as I said in the original post.

No, it isn't. But the question is not whether you are incapable of
implementing an effective emulation of 'protected' (in some meaningful
sense of the term) in javascript (obviously that if far beyond you), but
rather whether it can be done.

Having determined whether or not it can be done it becomes possible to
give an informed consideration as to whether it should be done (would
the overheads and authoring effort be justified by the result?). But
holding up a sequence of hollow imitations of some form of 'protection'
do not contribute at all to an understanding of the subject.

Richard.
 
R

Richard Cornford

VK said:
This is what I said:
<quot>
It means that protected/private/static/final stuff in them is
not a bulletproof lock but merely an "inconvenience protection"
(like locking

context menu on the page). You always can study the code and/or
spoof the constructor.
</quot>

Yes, it is an irrelevance to the subject of access modifiers.
If you would spend some of your precious time to read it.

I read it, but it just reminded me that you never let not knowing what
you are talking about prevent you from making a pointless noise.
Your beloved closures' tricks is *another* way but *not any
better* way.

Given that you are incapable of comprehending closures you are not
really in a good position to judge. What you proposed, apart from only
being functional on a limited number of implementations, fails to
control access to anything, while closures really can. Reasonable people
would consider the difference between effective and ineffective when
applying the label 'better'.
The question is only how many startup level users may it
stop from spoofing constructor.

You really don't get it do you?
I would say that your {cur{l}ed} way is more cryptic but
it's really a discussion whos code obfuscator is more
reliable (the real answer is: none of any).

There is no effort to obfuscate. Any apparent obfuscation is a feature
of your perception, as anything beyond your comprehension is bound to
seem obscure. Access modifiers, and particularly the nation of
'protected', are about _controlling_ which objects have access to which
properties of which object. That is, imposing those restrictions, and so
controlling how an object can be used.
Also:
try - catch - finally and throw are parts of JavaScript /
JScript for forever (by Internet time scale)

What relevance does support for try-catch have to anything that I said?
and any modern browser supports it
including Opera 8.x

Even opera 5 supported try-catch, what is your point?
Prehistoric and beta models (Opera 6.x, Netscape 3.x,
Netscape 6.x, Safari 1.x etc) are not subject of my
preoccupation in the mean of "make it work". But the
startup block in the script should let them
die peacefully.

When you say 'die peacefully' you actually mean error-out. Which is the
biggest demonstration of incompetence an author of Internet browser
scripts can make. Graceful degradation requires that scripts do not
error-out, but instead actively decide not to act where they are not
supported.
Nevertheless I'm not post each line of code here
as a turn-key solution with the startup block and
roll-back pages.

No, you posted enough to show an overly elaborate method of not
achieving anything useful, or anything at all on any but a couple of
browsers. So up to your usual standards.

Richard.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,822
Latest member
israfaceZa

Latest Threads

Top