defining classes-- different methods

C

Cliff Williams

Can someone explain the pros/cons of these different ways of creating a
class?


// 1
function myclass() {
this.foo1 = function() {...}
}

// 2a
function myclass() {}
myclass.prototype.foo1 = function() {...}

// 2b
function myclass() {}
myclass.prototype = { foo1: function() {...} }


I'm pretty sure 2a and 2b are equivalent-- please advise if this is
untrue.

I personally prefer method 1 since it seems to allow a notion of public
and private members. For example,

function myclass() {
var privateVar = "hi"
function privateFn() { return privateVar }
this.publicFn = function() { return privateFn() }
}

My personal preferences aside, the variations of method 2 seem to be
the standard. Can someone tell me why? Is there a way to accomplish the
aspects of method 1 I like with method 2? I sorta feel like I'm missing
a Big Idea :/

Thanks in advance...

Cliff
 
R

Richard Cornford

Cliff said:
Can someone explain the pros/cons of these different ways
of creating a class?


// 1
function myclass() {
this.foo1 = function() {...}
}

// 2a
function myclass() {}
myclass.prototype.foo1 = function() {...}

// 2b
function myclass() {}
myclass.prototype = { foo1: function() {...} }


I'm pretty sure 2a and 2b are equivalent-- please advise
if this is untrue.

They are equivalent to most practical purposes, but when a function
object is created the object assigned to its prototype property has a
reference to the function assigned to its - constructor - property,
which is not true of an object assigned to the prototype property of a
function (unless explicitly scripted). The - constructor - property of
objects has little practical use so the distinction between the two
methods is rarely significant.

It is also the case that when one 'class' inherits from another by
having and instance of the 'supreclass' assigned to the - prototype -
property of the 'subclass' s' constructor the value as the prototype's -
constructor - property will again not be a refernce to the subclass
constructor function (unless explicitly scripted).
I personally prefer method 1 since it seems to allow
a notion of public and private members. For example,

True, but remember that a function expression assigned within the
constructor will result in a unique function object being created for
each and every object instance created with the constructor, while each
instance inherits a reference to a single function object when its
methods are inherited from the object referred to by the constructor's
prototype Thus it is wasteful of resources to be assigning function
expressions to object methods inside the constructor whenever they are
not employing closures to emulate private members.
function myclass() {
var privateVar = "hi"
function privateFn() { return privateVar }
this.publicFn = function() { return privateFn() }
}

My personal preferences aside, the variations of method 2
seem to be the standard. Can someone tell me why?

It is the natural way of doing inheritance in javascript. Using any of
the alternatives (and there are considerably more than just these three)
should be an action following from an informed decision by the
programmer (that is, if asked it should be possible to clearly state why
the alternative was used, and enumerate the benefits that follow).
Is there a way to accomplish
the aspects of method 1 I like with method 2?

Yes. You just do it; the references to functions assigned in the
constructor will exist alongside the methods inherited from the
prototype (except where their names correspond, in which case the
methods assigned in the constructor mask the methods on the prototype
(which may be conceived as overloading the methods of a 'supreclass')).
I sorta feel like I'm
missing a Big Idea :/

You have not said anything about how you perceive what the code you
posted is doing, so whether you really understand it or not is
unknowable.

Richard.
 
C

Cliff Williams

Ah... two bits I forgot about when I was initially thinking about this
are the role of .prototype in inheritance and the fact that functions
are objects.

The lightbulb shines a little brighter... thanks for your help.
 
J

Jonas Raoni

Cliff Williams escreveu:
Can someone explain the pros/cons of these different ways of creating a
class?

// 1
function myclass() {
this.foo1 = function() {...}
}

Assigning things to "this" in the constructor are supposed to be part of
the initialization. So assigning "static" functions doesn't make sense
for me if you're not going to make a closure.
// 2a
function myclass() {}
myclass.prototype.foo1 = function() {...}

// 2b
function myclass() {}
myclass.prototype = { foo1: function() {...} }

They are similar, 2b looks better than 2a, but changes the "expected"
behavior of the constructor property.
I personally prefer method 1 since it seems to allow a notion of public
and private members. For example,

function myclass() {
var privateVar = "hi"
function privateFn() { return privateVar }
this.publicFn = function() { return privateFn() }
}

If you don't need to encapsulate variables, I don't see a point to use it :]
My personal preferences aside, the variations of method 2 seem to be
the standard. Can someone tell me why?

You're asking why it's the standard??? If yes, because this is the only
way I know to avoid making totally procedural codes.
Is there a way to accomplish the
aspects of method 1 I like with method 2? I sorta feel like I'm missing
a Big Idea :/

Hmmm, I don't like the term "private members" in JavaScript, you should
use the closures as a trick to store things inside the functions without
the need of sending them as arguments or creating new classes and store
the data inside the "this". So, there's no point in simulating the #1,
if you need it, use it ^^
 
R

Richard Cornford

Jonas said:
Cliff Williams escreveu:

Assigning things to "this" in the constructor are supposed to
be part of the initialization. So assigning "static" functions

In what sense is this assigning a "static" function? The term "static"
is usually used to draw parallels between languages that have a static
modifier for methods (such as Java) and so to refer to methods that are
'of the class' rather than 'of the class instance'. The method assigned
above certainly is 'of the class instance' (as each instance gets a
unique copy of the function object as one if its properties).
doesn't make sense
for me if you're not going to make a closure.

A closure is formed above. The act of assigning a reference to an inner
functions (whether it result form a function expression or a function
declaration) to a property of the object does that. It is not a useful
closure because there are no local variable, formal parameters or inner
function declarations in the outer function.

You're asking why it's the standard??? If yes, because
this is the only way I know to avoid making totally
procedural codes.

Is it really likely that things are standard because of limitations in
your knowledge? that is a really odd thing to say.

Richard.
 
V

VK

Cliff said:
Can someone explain the pros/cons of these different ways of creating a
class?


// 1
function myclass() {
this.foo1 = function() {...}
}

// 2a
function myclass() {}
myclass.prototype.foo1 = function() {...}

// 2b
function myclass() {}
myclass.prototype = { foo1: function() {...} }


I'm pretty sure 2a and 2b are equivalent-- please advise if this is
untrue.

It is untrue :)

All three ways are very different. The other question is that depending
on circumstances their differences may be crucial or not so important.

1) The first constructor in each invocation creates anonymous function
and assigns a reference to it to the new object instance. It means that
for 100 objects of the given class you will create 100 identical
function objects used as instance methods. This is why in a good style
of programming you use this way of constructing *only* if object
instances need to keep instance-specific data in methods. In any other
case it is vesting memory and obfuscating garbage collector's work. It
also complicates with no need the serialization process.

2) In the second case you are creating so-called "static" method. The
correctness of the term "static" in application to C-derivative
languages was discussed N times in the programming community, but each
time the traditions took over the semantic :) Any way, "static"
doesn't mean "non-changeable", "constant" or such. It means that all
object instances of the given class are sharing a single instance of
this method. So in the second case you are creating an anonymous
function and assigning a reference to it to the named property
"MyMethod" in the constructor's prototype. Respectively each new object
instance will get a named reference to this *single* function. As you
may guess, you cannot store instance-specific data in static methods
(unless using some sophisticated hacks: which automatically means that
you are using a wrong construction method and that you must switch onto
option (1)

3) In the tird case you are not *adding* a static method into prototype
as it was in case (2) Here you are *replacing* the entire prototype
object with new object having only one named property "MyMethod".
Respectively "SomeMethod" (see the sample below) gets lost. This way
this method may be used for base (super) constructor but should be
avoided in derivatives unless nuking method inheritance was your aim
;-)

I put a sample for studies below to illustrate these explanations. To
avoid irrelevant code complications, I simply used function
augmentation to show if you are dealing with different or the same
objects (MyMethod.foo = "bar").


<script type="text/javascript">
// Constructor One
function Constructor1() {
this.MyMethod = function(){};
}
// Constructor Two
function Constructor2() {
}
Constructor2.prototype.SomeMethod = function(){};
Constructor2.prototype.MyMethod = function(){};
// Constructor Three
function Constructor3() {
}
Constructor3.prototype.SomeMethod = function(){};
Constructor3.prototype = {'MyMethod':function(){}};

function init() {
///////
// One
var obj1_1 = new Constructor1;
var obj1_2 = new Constructor1;
obj1_1.MyMethod.foo = 'bar';
try {
window.alert(obj1_1.MyMethod.foo); // bar
window.alert(obj1_2.MyMethod.foo); // undefined
}
catch(e) {
window.alert(e.message);
}
///////
// Two
var obj2_1 = new Constructor2;
var obj2_2 = new Constructor2;
obj2_1.MyMethod.foo = 'bar';
try {
window.alert(obj2_1.MyMethod.foo); // bar
window.alert(obj2_2.MyMethod.foo); // bar
window.alert(typeof obj2_1.SomeMethod); // function
}
catch(e) {
window.alert(e.message);
}
///////
// Three
var obj3_1 = new Constructor3;
var obj3_2 = new Constructor3;
obj3_1.MyMethod.foo = 'bar';
try {
window.alert(obj3_1.MyMethod.foo); // bar
window.alert(obj3_2.MyMethod.foo); // bar
window.alert(typeof obj3_1.SomeMethod); // undefined
}
catch(e) {
window.alert(e.message);
}
}
window.onload = init;
</script>
 
J

Jonas Raoni

Richard Cornford escreveu:
Jonas Raoni wrote:
In what sense is this assigning a "static" function? The term "static"
is usually used to draw parallels between languages that have a static
modifier for methods (such as Java) and so to refer to methods that are
'of the class' rather than 'of the class instance'. The method assigned
above certainly is 'of the class instance' (as each instance gets a
unique copy of the function object as one if its properties).

So tell me, what term should I use to make you happy? Static has several
mine one is related said:
A closure is formed above. The act of assigning a reference to an inner
functions (whether it result form a function expression or a function
declaration) to a property of the object does that. It is not a useful
closure because there are no local variable, formal parameters or inner
function declarations in the outer function.
Yes.



Is it really likely that things are standard because of limitations in
your knowledge? that is a really odd thing to say.

I wonder how long you will keep losing your time criticizing the way I
write, there's nothing wrong in what I wrote. I already told you, I just
want to help with my few experience, not to be a teacher of feel myself
like a guru xD

If you see something *wrong* in my messages, just say it... I'll say
"cool, I didn't knew it" or "yes, I was wrong"... But if you don't have
nothing useful to add... Please, don't lose your time, you're making me
remember of that guy higher leveled troll "Thomas, the Pointed Ears"...
I lost a lot of time writing these two last messages, just because you
wanted to be boring :]

Brrrrrrr... I'll go sleep, I'm feeling exhausted, tomorrow everything
starts again xDDD
 
R

Richard Cornford

Jonas said:
Richard Cornford escreveu:

So tell me, what term should I use to make you happy? Static has
several meanings <URL:http://en.wikipedia.org/wiki/Static>, mine one
is related with something that doesn't change.

Whatever term unambiguously states what you want to say. It is perhaps
unfortunate that in the context of OO programming 'static' has a well
known (although obviously not to VK) and specific meaning, and we are in
the context of OO programming when talking of "defining classes" in
javascript.

I wonder how long you will keep losing your time criticizing
the way I write,

I am not criticising the way you write, I am criticising what you wrote.
there's nothing wrong in what I wrote.

You wrote that the reason something was standard was "because this is
the only way I know ...", and that is extremely improbable.
I already told you, I
just want to help with my few experience,

There is possibly a difference between having a desire to help and
having an ability to help. VK, for example, maintains that he has a
desire to help (though he may not be being honest in that assertion),
but mostly what he actually does is harm.
not to be a teacher of feel
myself like a guru xD

If you see something *wrong* in my messages, just say it...
<snip>

I did say it; asserting a relationship between what is standard in
javascript and your knowledge of javascript is odd. That statement is
almost certainly false.

Richard.
 
V

VK

Richard said:
It is perhaps
unfortunate that in the context of OO programming 'static' has a well
known (although obviously not to VK)

It is obviously known to me: as you may see from my post; from all
criticism you wrote in this thread this is the only "wording"
correction I may support: because indead calling the creation of
individual method instances for each object instance as "static" is way
too much of speech freedom :)
It is also the known fact that "static" term is very far of the real
nature of the phenomemon it describes. Well, as I said sometimes
traditions and the legacy have much more weight as any arguments of
correctness.
<http://mindprod.com/jgloss/static.html> by Roedy Green could be a
helpful startup reading (it is from his Java Glossary, but the "static"
meaning is analized in the global programming aspect).
Wiki is not as good but still very helpful:
<http://en.wikipedia.org/wiki/Static_method>

There is possibly a difference between having a desire to help and
having an ability to help. VK, for example, maintains that he has a
desire to help (though he may not be being honest in that assertion),
but mostly what he actually does is harm.

Are you commenting on my post in this thread or these are overall
abstract considerations? For the latter that could be easily avoided
really. For the first: what exactly you don't agree with and why in
<http://groups.google.com/group/comp.lang.javascript/msg/3c41e9f64c43f639>
(<[email protected]>)
 
R

Richard Cornford

VK said:
It is obviously known to me: as you may see from my post;

It is precisely your pose, and specifically where you characterise
instance methods inherited through the prototype as "static", that makes
it obvious that you do not comprehend the concept of 'static' as it used
in class-based languages:-

You wrote:-

| In the second case [Assigning methods to the prototype of
| the constructor] you are creating so-called "static" method.
| ...
| It [static] means that all object instances of the given class
| are sharing a single instance of this method.

- which is not what static means, it just may be a practical consequence
in some languages of what static does mean.
from all criticism you wrote in this thread this is the
only "wording" correction I may support: because indead
calling the creation of individual method instances for
each object instance as "static" is way too much of
speech freedom :)
Gibberish.

It is also the known fact that "static" term is very far of
the real nature of the phenomemon it describes. Well, as I
said sometimes traditions and the legacy have much more
weight as any arguments of correctness.
<http://mindprod.com/jgloss/static.html> by Roedy Green
could be a helpful startup reading (it is from his Java
Glossary, but the "static" meaning is analized in the
global programming aspect).

<quote cite=" http://mindprod.com/jgloss/static.html">
They [static methods and variables] are the opposite of instance
variables and methods that work on a particular object.
....
static refers to a method or variable that is not attached to a
particular object, but rather to the class as a whole.
....
static methods work without any this object.
....
static methods and variable are in a sense inherited, but not in the
same strong sense that instance variables and methods are.
</quote>

Methods assigned to the prototype of a constructor are instance methods,
they work on a particular object, using the - this - reference, they are
inherited (which is the whole point of assigning to the prototype) and
they are attached to a particular object (though indirectly through the
prototype chain).
Wiki is not as good but still very helpful:
<http://en.wikipedia.org/wiki/Static_method>

<quote cite="http://en.wikipedia.org/wiki/Static_method">
Static methods

As mentioned above, a method may be declared as static (or shared in
VB), meaning that it acts at the class level rather than at the instance
level. A static method cannot refer to a specific instance of the class
(i.e. it cannot refer to this, self, Me, etc.)
</quote>

And an object assigned to the prototype _can_ refer to an object
instance that inherits it using - this -.

In erroneously fixating on the singleness of the function object
referred to through the prototype chain you are missing the true nature
of a static method; to be "of the class" and fooling yourself into
thinking that instance methods are "static" because of a coincidental
characteristic of prototype-based inheritance.

It is in an appreciation of the concept of "static" in OO programming
that you are deficient, and the nonsense you write as a result of
typical.
Are you commenting on my post in this thread or these are
overall abstract considerations?

You mean like your garbled 'explanations' of your misconceptions of
javascript, and programming in general? Your habit of invariably
choosing the worst approach available to any coding problem for
yourself, and then proposing those approaches to others who don't know
enough to judge how bad they really are? The extent to which corrections
to your posts consume the time that could be offered to the more
deserving (particularly when you pointlessly argue that you are correct,
only to eventually, and inevitably, be demonstrated wrong)? The way you
encourage newcomers to the group to create badly formed posts (by
example and by tolerating their poorly formatted posts) and so inhibit
their ability to receive assistance from many of the more knowledgeable
contributors to the group?
For the latter that could be easily avoided
really.

Yes, you do have the power to avoid doing the harm you do. Your complete
silence would be one possibility, and your starting to do something
about learning programming, javascript and web development related
technologies would be another.
For the first: what exactly you don't agree with
and why in
<http://groups.google.com/group/comp.lang.javascript/msg/3c41e9f64c43f63
9>
(<[email protected]>)

Its contents. It is extremely unlikely that your aggregation of poorly
expressed misconceptions, obfuscated with irrelevancies, would be of any
service to any reader of that post. Nobody would be in a position to be
a better author of OO javascript as a result of reading it, which is
hardly surprising given how very bad at it you have demonstrated
yourself as being over the last few years.

Richard.
 
V

VK

Richard said:
It is precisely your pose, and specifically where you characterise
instance methods inherited through the prototype as "static", that makes
it obvious that you do not comprehend the concept of 'static' as it used
in class-based languages:-

No, it just illustrates really well why am I having such troubles to
communicate with you and with some other regulars in this group:
because of an extremely chaotic approach to the inheritance questions.
Depending on circumstances one either fixates on "visual difference"
(this lion is brown, this lion almost yellow, so the second one is not
lion) or on "visual similarity" (lion has a tail, tiger has a tail, so
both are the same animal). The first issue is illustrated by the
current "static" discussion; the second one leads to the non-sense like
"Array is Object, just with that funny length property added" (Array is
an object by it is not the Object: but it inherits from and extends
base Object constructor).

Without too much hope to change your mindset but to protect other
potential thread readers: as it was explained in my post JavaScript
implements static and per-instance methods as well as other C-languages
do - with necessary differences implied by different inheritance
models.

I thought I provided enough of reading but you seem jumped on the
possibility to reference static methods in JavaScript by [this] keyword
- as it's the core reason do not be static. It has nothing to do with
being static or not being static. Maybe more basic reading would help:
<http://java.sun.com/docs/books/tutorial/java/javaOO/classvars.html>
"Note: You can also refer to static fields with an object reference
like
myBike.numberOfBicycles
but this is discouraged because it does not make it clear that they are
class variables."

(In JavaScript case we necessarily change "class variable" to
"prototype variable" and "discouraged" has no much weight).

<script type="text/javascript">
function C() {
this.personal = new Function;
}
C.prototype.shared = new Function;

var obj1 = new C;
var obj2 = new C;

alert(obj1.personal === obj2.personal); // false
alert(obj1.shared === obj2.shared); // true

alert(obj1.hasOwnProperty('personal')); // true
alert(obj1.hasOwnProperty('shared')); // false
</script>
 
R

Richard Cornford

VK said:
No, it just illustrates really well why am I having such troubles to
communicate with you and with some other regulars in this group:

Are you about to argue that you are right and everyone else is wrong,
again?
because of an extremely chaotic approach to the inheritance questions.

It is hardly anyone else's fault that you still do not understand how
inheritance works in javascript, it has been explained to you often
enough.
Depending on circumstances one either fixates on "visual difference"
(this lion is brown, this lion almost yellow, so the second one is not
lion) or on "visual similarity" (lion has a tail, tiger has a tail, so
both are the same animal).

It is hardly any one else's fault that you don't comprehend logic.
The first issue is illustrated by the
current "static" discussion; the second one leads to the non-sense like
"Array is Object, just with that funny length property added"

An array is an object, with a special [[Put]] method that modifies its
- length - property when 'array index' property names are used with it
and sometimes its 'array index' properties when the property name
'length' is used with it.
(Array is an object by it is not the Object: but it inherits from and
extends base Object constructor).

There is no sense in "inherits from and extends base Object
constructor". The constructor is a function object and Arrays do not
inherit from function objects. They inherit from the object that is the
original value of - Object.prototype -, and do so through the object
that is the value of - Array.prototype -. In a language that uses
prototype inheritance it is prototypes that are inherited from.
Without too much hope to change your mindset

Zero. You are wrong, so the only person who needs to change their mind
is you.
but to protect other potential thread readers:

You mean add to the harm you have already done with additional
misconceptions and more irrelevant misdirection?
as it was explained in my post JavaScript implements static and
per-instance methods as well as other C-languages
do -

The C language does not include static or per-instance methods (that is
what C++ adds). And javascript is not a C-language, it is a language
with a C-like syntax, but more closely related to List, Self and
Scheme.
with necessary differences implied by different inheritance
models.

I thought I provided enough of reading but you seem jumped on the
possibility to reference static methods in JavaScript by [this] keyword

Yes, that is a very significant difference between a static method and
an instance method; an instanced method may refer to its own object
instance with the - this - keyword, and a static method cannot because
being "of the class" it does not relate to any single object instance.
- as it's the core reason do not be static.

It is sufficient reason alone. It was not the only reason that I
stated.
It has nothing to do with being static or not being static.

So why is it stated as a distinction between instance methods and
static methods in both of the definitions of static that you cited?
Maybe more basic reading would help:

It might help you, though understanding the words used in what you have
read would be more useful to you.

<quote
cite="http://java.sun.com/docs/books/tutorial/java/javaOO/classvars.html">
Class methods cannot access instance variables or instance methods
directly-they must use an object reference. Also, class methods
cannot use the this keyword as there is no instance for this to refer
to.
"Note: You can also refer to static fields with an object reference
like
myBike.numberOfBicycles
but this is discouraged because it does not make it clear that they are
class variables."

Discouraged because instance method can be referenced in the same way,
and so no distinction between the two is apparent in the code. But
being able to write:- myBike.instanceUniqueId - does not make -
instanceUniqueId - a static member just because it has the same form as
one that may be used to access a static member.
(In JavaScript case we necessarily change "class variable" to
"prototype variable" and "discouraged" has no much weight).

Prototypes, and modifications to those prototypes are used to define
and default instance variables/methods, so it would be very foolish to
use 'prototype variable' in place of 'class variable'.
<script type="text/javascript">
function C() {
this.personal = new Function;
}
C.prototype.shared = new Function;

var obj1 = new C;
var obj2 = new C;

alert(obj1.personal === obj2.personal); // false
alert(obj1.shared === obj2.shared); // true

alert(obj1.hasOwnProperty('personal')); // true
alert(obj1.hasOwnProperty('shared')); // false
</script>

Again you post code with no explanation of what you think it is
supposed to be demonstrating. (If you are going to complain that you
have trouble communicating maybe you should consider that your failure
to explain code that you post as 'examples', and for that matter your
failure to answer any of the questions you are directly asked, might
significantly contribute to that.)

You are letting the identity of function objects confuse you about the
roles and status of the methods used here. All of the method assigned
are instance methods (regardless of the number of function objects used
to implement each). You can tell that they are instance methods because
in each the - this - keyword can be used to reference the individual
object instances.

A simpler distinction between static and instance may be demonstrated
with a non-method property. If such a property was static then its
single value would be shared by all instances of a class, and all
instances of that class could modify the value, resulting in all
instances of the class seeing the modified value.

So if you define a property on a prototype, as:-

function AnObject(){
;
}
AnObject.prototype.someValue = 5;

- and create two instances of AnObject:-

var a = new AnObject();
var b = new AnObject();

- reading the value of - someValue - will return the default value
defined by the assignment to the prototype's property:-

alert(a.someValue); // alerts 5
alert(b.someValue); // alerts 5

Now if - someValue - as a static member of the class (a 'class
variable') an assignment of a new value to - someValue - from any
instance would modify the results obtained from reading the property
from all instances. So:-

a.someValue = 8;

- would result in instance b alerting 8 from:-

alert(b.someValue);

- but it still alerts 5. The - someValue - properties of the object
instances are instance variables, they just have default values that
they inherit from a prototype (and because the prototype is dynamic the
default value may be subject to runtime modification).

In javascript it is completely feasible to create variables and methods
that are static (are "of the class") and that work in a way that
satisfies the concept of 'static' as it is used in class-based
languages, but the properties of the prototype are not capable of
satisfying that role.

Richard.
 
V

VK

I personally prefer method 1 since it seems to allow a notion of public
and private members. For example,

function myclass() {
var privateVar = "hi"
function privateFn() { return privateVar }
this.publicFn = function() { return privateFn() }
}

As explained in my previous post, it is irrelevant whether you need an
emulation of protected scope for your method or not; what is relevant
is whether you need per-instance protected scope or just one protected
scope for all instances (so their getter/setter methods will work on
competition basis). The latter is rather dangerous doing because
JavaScript doesn't have synchronized modifier so the execution flow can
get really fancy :) In any case it is yours to decide.

1) Per-Instance protected scope (string variable in this sample)

<script type="text/javascript">
function MyObject(arg) {
// Overriding toString method to prevent
// source dump. This method is static so
// shared by constructor and all instances:
this.toString = MyObject.toString;
// Create instance-specific protected scope
// and provide getter/setter accessors to the
// current instance:
ProtectedScope.call(this, arg);
function ProtectedScope(arg) {
this.getPrivate = getPrivate;
this.setPrivate = setPrivate;
var $default = 'foo';
var $private = (typeof arg == 'string') ? arg : $default;
function getPrivate() {
return $private;
}
function setPrivate(arg) {
$private = (typeof arg == 'string') ? arg : $default;
}
}
}
MyObject.toString = function() {
return 'function';
// ... or some bogus function body code
}

var obj1 = new MyObject('foobar');
var obj2 = new MyObject;
obj1.setPrivate('bar');
alert(obj1.getPrivate()); // 'bar'
alert(obj2.getPrivate()); // 'foo' (default)
</script>

There is few catches in here.
First of all, inner functions (inner classes in some other languages)
is what is called "undocumented language feature". It is entirely based
on the fact that any good written engine will try to interpret any code
as long as it's syntactically correct. At the same time while making
the original JavaScript specs no one in the wildest dream wouldn't
imagine a code like function a(){function b(){function c(){}}} not only
being used - but being nearly a core of many solutions. It doesn't mean
do not use it: but it means use with care and check every outcome on
every engine of your interest.

Secondly, as Jonas Raoni already pointed out, regular JavaScript
doesn't have private or protected modifiers. So the max one can do is
to emulate it by carefully applying closure mechanics. In the sample
above despite "visually" we are dealing with the same inner function
ProtectedScope, in fact we are forming new closure (thus separate
scope) for each object instance.

AFAICT Cornford-Crockford (CC) scope management doesn't allow purely
static protected members: that is an implication of a solution based on
closures. The max you can do is to have static compound property
("protected variable" in CC) which is shared among all class
instances: but getter/setter for this property ("privileged methods" in
CC) will be individually cloned for each class instance.

P.S. "class instance" term is used in application to the objects
produced by function-constructor.
 
V

VK

Richard said:
So if you define a property on a prototype, as:-

function AnObject(){
;
}
AnObject.prototype.someValue = 5;

- and create two instances of AnObject:-

var a = new AnObject();
var b = new AnObject();

- reading the value of - someValue - will return the default value
defined by the assignment to the prototype's property:-

alert(a.someValue); // alerts 5
alert(b.someValue); // alerts 5

Now if - someValue - as a static member of the class (a 'class
variable') an assignment of a new value to - someValue - from any
instance would modify the results obtained from reading the property
from all instances. So:-

a.someValue = 8;

- would result in instance b alerting 8 from:-

alert(b.someValue);

- but it still alerts 5. The - someValue - properties of the object
instances are instance variables, they just have default values that
they inherit from a prototype (and because the prototype is dynamic the
default value may be subject to runtime modification).

Are you kidding me or is it a "straw man" tactics? On property access
request the property is first searched in the object instance, if not
found (and only if not found) it is searched along the inheritance
chain (from prototype to prototype). Originally "a" doesn't have
someValue property, so the engine looks for it in the prototype. Then
you create someValue property with value 8 so the engine doesn't look
for it anymore in the prototype: but the prototype value itself doesn't
change and it doesn't disappear. In the programming it is called
"shadow something".

Respectively all other instances do not have the inherited value
shadowed by own property.

<script type="text/javascript">
function C() {
;
}
C.prototype.n = 5;

var obj = new C;
alert(obj.n); // 5
alert(obj.hasOwnProperty('n')); // false
obj.n = 8;
alert(obj.n); // 8
alert(obj.hasOwnProperty('n')); // true
alert(obj.constructor.prototype.n); // 5
</script>
 
V

VK

VK said:
On property access
request the property is first searched in the object instance, if not
found (and only if not found) it is searched along the inheritance
chain (from prototype to prototype). Originally "a" doesn't have
someValue property, so the engine looks for it in the prototype. Then
you create someValue property with value 8 so the engine doesn't look
for it anymore in the prototype: but the prototype value itself doesn't
change and it doesn't disappear. In the programming it is called
"shadow something".

Respectively all other instances do not have the inherited value
shadowed by own property.

<script type="text/javascript">
function C() {
;
}
C.prototype.n = 5;

var obj = new C;
alert(obj.n); // 5
alert(obj.hasOwnProperty('n')); // false
obj.n = 8;
alert(obj.n); // 8
alert(obj.hasOwnProperty('n')); // true
alert(obj.constructor.prototype.n); // 5
</script>

Respectively to change a static property you have to *change* that
property, not *shadow* it in selected instances:

<script type="text/javascript">
function C(){
;
}
C.prototype.n = 5;

var obj1 = new C;
var obj2 = new C;
alert(obj1.n); // 5
alert(obj2.n); // 5
obj1.constructor.prototype.n = 8;
alert(obj1.n); // 8
alert(obj2.n); // 8
</script>

P.S. OT: I'm an IQ monster :) At 5am I'm eating an open face turkey
sandwich by one hand and explaining JavaScript inheritance by other
hand. I'm ready to be an astranaute I guess :)
 
B

Bart Van der Donck

VK said:
[...]
function ProtectedScope(arg) {
this.getPrivate = getPrivate;
this.setPrivate = setPrivate;
var $default = 'foo';
var $private = (typeof arg == 'string') ? arg : $default;
function getPrivate() {
return $private;
}
function setPrivate(arg) {
$private = (typeof arg == 'string') ? arg : $default;
[...]

Any reason for the sigils, or just personal preference ?
 
R

Richard Cornford

VK said:
As explained in my previous post,
LOL

it is irrelevant whether you need an emulation of protected scope
for your method or not; what is relevant is whether you need
per-instance protected scope or just one protected scope for
all instances (so their getter/setter methods will work on
competition basis).

Don't be silly, if no emulation of protected members is necessary it
don't matter at all whether they are not instance members or not class
members.
The latter is rather dangerous doing because
JavaScript doesn't have synchronized modifier so the execution flow can
get really fancy :)

Javascript is single threaded so it does not need any synchronisation
mechanism.
In any case it is yours to decide.

1) Per-Instance protected scope (string variable in this sample)

The code you post is usually illustrative of the consequences of your
legion misconceptions about javascript.
<script type="text/javascript">
function MyObject(arg) {
// Overriding toString method to prevent
// source dump. This method is static so
// shared by constructor and all instances:
this.toString = MyObject.toString;

This is pointless and your justification is bogus and dishonest, as the
- toString - method inherited from the original - Object.prototype -
returns "[object Object]", which is hardly something that represents a
"source dump".
// Create instance-specific protected scope
// and provide getter/setter accessors to the
// current instance:
ProtectedScope.call(this, arg);
function ProtectedScope(arg) {
this.getPrivate = getPrivate;
this.setPrivate = setPrivate;
var $default = 'foo';
var $private = (typeof arg == 'string') ? arg : $default;
function getPrivate() {
return $private;
}
function setPrivate(arg) {
$private = (typeof arg == 'string') ? arg : $default;
}
}
}
MyObject.toString = function() {
return 'function';
// ... or some bogus function body code
}

This is pretty much pointless as if other code wanted to get a string
represen5taion of the constructor's source (which is pretty pointless
itself) it only has to delete the - toString - property of this object
to re-expose the original - Function.prototype.toString -
value,directly assign that value to the - toString - property of this
object (overwriting this method), or use the - apply - or - call -
methods of the original - Function.prototype.toString - method.

Now let's see that code implemented without the obfuscating
convolutions and utterly pointless actions:-

function AnObject(arg){
var value = (typeof arg == 'string')? arg:'foo';
this.getPrivate = function(){
return value;
};
this.setPrivate = function(v){
value = (typeof v == 'string')? v:'foo';
};
}
AnObject.toString = function(){
return 'function';
};

- Now isn't that considerably simpler and clearer? (and inevitably much
more efficient as well).
var obj1 = new MyObject('foobar');
var obj2 = new MyObject;
obj1.setPrivate('bar');
alert(obj1.getPrivate()); // 'bar'
alert(obj2.getPrivate()); // 'foo' (default)
</script>

There is few catches in here.
First of all, inner functions (inner classes in some other languages)
is what is called "undocumented language feature".

Nonsense. Inner functions are a fully specified feature of all ECMA
262, 3rd edition implementations.
It is entirely based on the fact that any good written engine will try
to interpret any code as long as it's syntactically correct.

It is completely based upon a formal language specification.
At the same time while making
the original JavaScript specs no one in the wildest dream wouldn't
imagine a code like function a(){function b(){function c(){}}} not only
being used - but being nearly a core of many solutions.

If that were true the specification would not tell you precisely how
that code is to be interpreted and executed in precise detail, which it
does.

The limitation you are describing here is yours. You cannot comprehend
the specification so you assume that what you do not perceive in it is
not there. In reality ECMA 262 states precisely how any syntactically
correct javascript source code permutation that can be created will be
executed. That is, after all, what a computer language specification
must do in order that it may be implemented.
It doesn't mean do not use it: but it means use with care and
check every outcome on every engine of your interest.
Nonsense.

Secondly, as Jonas Raoni already pointed out, regular JavaScript
doesn't have private or protected modifiers. So the max one can do is
to emulate it by carefully applying closure mechanics. In the sample
above despite "visually" we are dealing with the same inner function
ProtectedScope, in fact we are forming new closure (thus separate
scope) for each object instance.

And doing so in a pointlessly convoluted way.
AFAICT Cornford-Crockford (CC) scope management doesn't allow
purely static protected members:

The list of things you cannot tell about javascript is extensive.
that is an implication of a solution based on
closures. The max you can do is to have static compound property
("protected variable" in CC) which is shared among all class
instances: but getter/setter for this property ("privileged methods" in
CC) will be individually cloned for each class instance.
<snip>
Nonsense.

Richard.
 
V

VK

Bart said:
Any reason for the sigils, or just personal preference ?

The sigil itself in "tentatively private member" name is for more easy
"visual" code navigation between the team members plus for automated
POD generation (Hungarian notation would be way too "heavy" for
JavaScript).
"$" for sigil instead of say underscore is a personal preference (a
subconscious Perl influence maybe :)
 
R

Richard Cornford

VK wrote:
Are you kidding me or is it a "straw man" tactics?

I am showing you that prototypes are used for defaulting instance
variables and methods and have no relationship with concepts behind the
use of the term 'static' in class-based languages. Regardless of the
fact that there is only ever a single default value that single value
is not conceptualy "of the class", it is a default for the instance.

Richard.
 
R

Richard Cornford

VK said:
Well, if you are serious in what you are saying then your perception of
JavaScript and especially its inheritance is seriously damaged.

As if you could tell.
<script type="text/javascript">
function C() {
;
}
C.prototype.n = 5;

var obj = new C;

alert(obj.n); // 5

// n is not own instance property,

It looks like you are referencing it as a property of an instance to
me.
it is
// static property provided through the
// prototype inheritance:

It is an instance property defaulted though inheritance from the
prototype.
alert(obj.hasOwnProperty('n')); // false

// shadow inherited property by own property
// with the same name:
obj.n = 8;
alert(obj.n); // 8
// this n is own instance property
// but it has nothing to do with the
// inherited static property n:
alert(obj.hasOwnProperty('n')); // true

The actual value of the instance property is now held on the object
instance itself rather than being inherited from the prototype. That is
the nature of javascript's inheritance.
// inherited property itself is still there
// but it's shadowed by instance's own property:
alert(obj.constructor.prototype.n); // 5

// remove the own property shadowing
// the inherited one:
delete obj.n;

// inherited property is visible again:
alert(obj.n); // 5
alert(obj.hasOwnProperty('n')); // false
</script>

You are still fixating on the singleness of the values stored on the
prototype as indicating that they are 'static'. That singleness is
irrelevant to the concept of static in class-based languages, it is
just a feature of how javascript's object instances are defined.

A simple parallel can be found in Java's class definitions. When you
declare an instance member you can default its value, and all instances
will then have that value until they assign a new value to that member
(or a new value is assigned from outside, if possible). Nobody would
consider those default values 'static' and they are certainly not
declared as such.

Javascript is not a class-based language and has no modifiers, but if
the terminology from class-based languages is going to be applied to
its constructs they should be applied where javascript constructs
parallel the concepts being spoken off.

The mechanism that defaults the values of object instance members is
not a suitable target for the term 'static', and it is not a term that
applies to parallel mechanisms in class-based languages. The fact that
the values that are used to default are singular is just a feature of
that mechanism, and has no significance beyond that.

As with class-based languages, the features of javascript that may
reasonable be termed 'static' are those that relate to the class. They
are most often manifest in the notion of 'public static' members, being
properties of the constructor function. Such properties satisfy every
aspect of the definitions of 'static' that you have posted references
to, and being properties of the constructor they are referenced in a
way that makes it obvious that they relate to the class as a whole and
not its instances.
P.S. Which is a proof that despite your own many times stated believe
it is possible to write working sophisticated programs even with
serious misconceptions about the used language ;-)

Is it? Where is this "sophisticated program" then?

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,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top