rickeringill@esriaustralia.com.au wrote:
<snip>
Quote:
Quote:
>Closures can be hard to grasp, but you've just stumbled across an
>example of one - I think that's the root of your confusion.
>>
>Try this simple example:
>>
> function Blah(){
>>
> // Local variable x
> var x = 'foo';
>>
> Blah.prototype.setX = function(){
>>
> // Create a closure back to Blah's local variable x from
> // the anonymous function object attached to Blah.prototype
> x = 'bar';
> }
>>
> Blah.prototype.showX = function(){
>>
> // Create another closure back to Blah's local variable
> // from the anonymous function object attached to Blah.prototype
> alert(x);
> }
> }
>>
> var a = new Blah();
> a.showX(); // Shows foo
> a.setX(); // Changes x to bar
> a.showX(); // Shows bar
>>
> var b = new Blah(); // Re-sets x to foo
> b.showX(); // Shows foo
> a.showX(); // Shows foo !!
>>
> // And to labour the point...
> a.setX(); // sets x back to bar
> b.showX(); // Shows bar
> a.showX(); // Shows bar
>>
>Note a.setX() changed the value of Blah's local variable x. When 'b'
>was constructed, the call to Blah re-set x to its original value.
>Since setX refers to Blah's local x, it appears to change for both 'a'
>and 'b'.
>>
>[...]
>>
Great, thanks for this little snippet - I hadn't spotted this before. I
have a feeling you've spared me a number of future headaches!
>
But now I'm confused. As you've shown above, when accessed
by methods of an object's prototype, a 'private' variable in fact
behaves like a 'private static' variable (ie. shared across all
instances of the object's 'class').
You have confused yourself by assigning functions objects as properties
of the constructor's prototype from within the constructor. The way in
which the constructor's internal variables are shred 'all instances or
the object's class' is that the first instance created has access to
the variables created during the invocation of its constructor up until
the point where a second instance is created and the functions referred
to by its prototype are changed, and then it shares access to the
variables created in the constructor function during the creation of
the second instance, with that instance. And then when a third instance
is created it and all previously created instances share access to the
local variables created in the constructor invocation that created the
third instance, and so on.
That is a long way from resembling a private static member in a
class-based languages, and is an approach likely to produce chaotic
code.
Quote:
Yet when accessed by 'privileged' methods, it
behaves like object level 'private' variable (replace
"Blah.prototype" with "this" above to see this effect).
Why is there this difference in behaviour?
Chaotic code exhibits chaotic behaviour? You are probably going to be
better off stopping trying to conceptualise this in Class-based terms
and trying to state what it is you are trying to achieve and why.
<snip>
Quote:
Quote:
>It is possible to do that as long as you don't access any local
>variables. As soon as you do, they become 'privileged' (their
>status as private, public, etc. is deduced from their access
>privileges, not necessarily by how or where you declare them).
>>
I would have said that their public/private/privledged status is
defined by what is available within the scope of the method rather
than just saying method foobar( ) is public because it doesn't
access any 'private' variables available in its' scope...
"Available within the scope"? That seems an oversimplification of the
situation couched in inadequate/inappropriate terminology. For
executing code there is a scope chain, against which Identifiers are
resolved, and with which closures work (and so by extension any
emulation of 'private' members). Objects have properties and they are
always accessible (so broadly 'public') and then objects have prototype
chains through which they inherit properties from other objects. Mostly
it is the distribution of values through out the properties of objects
in these distinct structures that influences how accessible they are.
<snip>
Quote:
Quote:
>The fact that they have access to local variables makes them
>privileged. To make them 'public', only give them access to
>privileged methods and stop referencing private variables.
>>
"only give them access" <-- the only way I can see how get the
language to enforce this is to do this is move the 'public' methods
outside of the 'constructor', thus removing the 'private' members
out of scope. Is there some other way?
There is a terminology confusion here. A public method is a method that
is accessible as a property of an object. A privileged method is a
method that is public but also has the ability to access otherwise
inaccessible local variables and inner functions.
Quote:
Quote:
>Your closures back to the constructor's properties means that
>what you thought was 'public' is 'privileged'.
OK, think we're talking cross purposes here. I guess in part I'm
trying to put forward the proposition that the use of the terms
'priviledged' and 'public' are not ideal.
They get the job done. Your initial motivation for this thread was that
method that were actually privileged seemed to you to be 'public'
methods, so privileged seemed redundant. Once you see that those method
were privileged all along it would be difficult to continue to maintain
that.
Quote:
If we're going to hijack terminology from OO to describe javascript
constructs, I'd have thought the use of the terms should be
consistent with their original purpose.
>
To me, proper 'public' methods in OO languages have access to all
(including private) members of the same class [at least in every OO
language I know].
While in the class-based OO languages I know the access qualifiers
don't have nay relevance for a method's ability to access members of
instances/classes/packages. The member's own access qualifiers
determine how visible they are to methods. And the access qualifiers of
method determines how visible the methods themselves are.
Quote:
In javascript land, this kind of access is currently
termed 'priviledged'.
Privileged methods are public methods with an ability to access
additional properties. They don't necessarily have access to "all
(including private) members of the same class", though they could if
programmed that way. (It is mostly a matter of writing the code that
gives you the best implementation of what you want)
Quote:
What are currently called 'public' methods for
javascript have no parallel in any OO language I know...
If anything it is the public methods that have the best parallel with
class-based languages as public methods are visible as properties of
objects to all other code.
<snip>
Quote:
Quote:
Quote:
>>* Is this allowable according to the ecmascript spec?
>>
>Absolutely. ...
<snip>
Quote:
I was more referring to the legality of the addition of properties
to an object's prototype from within the method which is actually
creating the object.
Being able to do something does not necessarily make doing it a good
idea. The code you wrote is inefficient and chaotic in regard to its
'static' aspects. It would be a good idea to understand prototype
inheritance before trying runtime modification to the properties of an
object on a prototype chain.
Quote:
If it works in Firefox then that's good enough for me. ;-)
Firefox is not definitive.
Richard.