1) The proposed term: "shared stateless". Functional similarity to
I see what you're saying, but I don't agree it's the right way to go
about explaining inheritance in JS.
We are not explaining the inheritance in JS so far: we are explaining
the inheritance, template (class or prototype), instance,
encapsulation, property and method as concepts and how do they go by
"one per instance" vs. "one for all" distinction. If none of it can be
explained without using some specific programming language and exact
entities of this specific language then we have to sorrily admit then
that OO (OOP) doesn't exist as a concept as well: there is then only a
loose set of unrelated language-specific techniques. I do think that
it is not true.
That would be better(?) maybe if for anything language-specific
language makers would be using newly made words like whatchamacallit,
whatchamacallthis, whatchamacallthat etc. This way for explanation one
could freely use the regular English words like class, prototype,
final etc. in their common meaning. But expectedly - and btw thanks to
that - the makers are normally using regular English words in a new
applied meaning for language keywords.
This is why I was calling in previous post to avoid a hysteria each
time a word may have a semantical slash with this or that programming
language. Just let's take a deep breath and try to find a unused
synonym if such semantical slash is _indeed_ so serious and leading to
misunderstanding.
In this aspect the usage of "a template" instead of "a class" or "a
prototype" seems justified(?) while "an instance" just fine as it is.
"shared" instead of "static" is definitely justified in view of C vs.
VB vs. C++/Java usages.
The other terms and necessary - if necessary - alternatives can be
discussed as it goes.
First off, I was talking about javascript, not java. It's very easy to
do this in JS, and AFIAK not at all possible in java (I don't know
enough about java introspection to rule it out completely).
The introspection as like:
http://en.wikipedia.org/wiki/Introspection_(computer_science)
?
How about
this (perl) example:
my %params;
sub semi_static_method {
my ($class,$param) = @_;
$params{$class} = $param;
}
This is a particular case of the method augmentation. As I said
before
(
http://groups.google.com/group/comp.lang.javascript/msg/
6e2d3d616109b87c) :
" this.method = new Function(args, code);
will not have state in any case unless a secondary function
augmentation which is kind of out of subject right now"
The above applies as well to the secondary augmentation of shared
stateless methods: it is possible, sometimes used, but it has very
weak relation with OOP matters. If we straighten up all this stuff
then it comes to something simple like:
var extraStorage = {};
function MyObject(key) {
this.key = key;
extraStorage[key] = this;
}
MyObject.prototype = function() {
// do with extraStorage[this.key];
}
Other words these are the same owned (per instance) methods just
"outsourced" for whatever reason over shared method used as some kind
of interface.
It's not pointless exactly. The interpretation of "this" in JS
functions/methods and the how/if inheritance is resolved is completely
defined by how the function/method is called. IMO trying to push a
class/instance view of the OO world is misleading at best.
Not class/instance because of potential semantical collision: but
template/instance view. Here there is nothing to push because it does
definitely exists in Javascript and extensively used in any modern
program. The "push" can be used only to the OOP itself: because
technically and practically it is possible to write plain linear
programs in Javascript without any prototypes and/or custom methods,
only with subroutines calling other subroutines etc. OOP in Javascript
is not the only way to program: it is only the most suggested - or
"pushed" if you want.
See above. Also, you didn't make it at all clear that you meant
per-object state and not per-class state; per-class state is easy in
most langauges. And then there are closures.
I am not sure I was using "per-object state" and "per-class state"
terms pair. When using "state" or "stateless" I am referring to the
state of a method in application to an object instance: say each
instance has its own Counter variable in its method and its value may
be different for each instance at once. Therefore "per-class state" is
not bearing too much sense to me. Unless you are talking about derived
classes over mutable constructors, like:
function outer(val) {
return function inner() {
this.property = val;
}
}
var f1 = new outer("foo");
var f2 = new f1;
// f2.property == "foo" over closure
// in the mutable constructor
My personal attitude to the closure-based inheritance is strictly
negative, but we will definitely talk about it - I mentioned it in my
original post. I just would like do not jump on everything at once:
before learning to mix things together it is most useful to study the
ingredients first. This is actually why I started this thread because
I am not satisfied at all by existing Javascript inheritance articles.
The amount of strange code samples and questions like "what a hey
prototype is?!" suggest that many Javascript beginners do not get them
as well. IMHO 99% of existing materials can be divided in two groups.
One is "canonical", where slightly altered quotations from ECMAScript
docs are illustrated by one-two samples. Normally readers are leaving
such articles with the knowledge that "Javascript doesn't have
classes, it is prototype based" - thus one obscure sentence more than
they knew before start reading such article, so even lesser than
before
The other type is "hackerly". This type style appeared at the
beginning of this century and still bearing IMHO the inferiority
complex of times when Javascript was considered as a lightweight toy
language for form pre-validation and so. As the result the authors
first trying to show how complex, tricky and misunderstood Javascript
can be. So instead of clear step-by-step explanations of the most used
everyday techniques they are dropping their readers into some complex
diagrams, samples where prototype is not prototype, constructor is not
constructor, instance is not instanceof and anything else from
undocumented and badly documented engine behavior.
I would really like to stay in the middle. So are closures, mutable
constructors, constructor != function constructor etc. possible? Yes,
of course. But let's hold the breath till the appropriate moment for
that ;-)
Let's us finish with the basic terms and pure prototype inheritance
first.
I just don't see the point of doing this at all, unless some objects
constructed using this function do have different methods. The only
other explanation is that you're micro-optimizing for method calls.
"micro-optimizing" for sure, up to "macro-optimizing" in many
circumstances because in Javascript internal object references are not
reusable. But I guess I am breaking my own intention to go step-by-
step. Overall it is just the ol'good OOP method as it was at beginning
of JavaScript and during the most of the Browser Wars. It is only
adjusted in respect of the modern taboo-demand to keep the global
namespace as clear as humanly possible. In some 1997/98 it simply
would be like:
function VK_MyObject() {
this.method = VK_method;
}
function VK_method() {
// ...
}
Yeah I know. So why not put the method in the prototype. At the very
least it will reduce the amount of code, and will make instantiation
objects cheaper.
Sometimes, yes. Pure canonical prototype inheritance has its caveats
as well though. We will talk about it after we decide what terms to
use in explanations and after actually explaining the pure canonical
prototype inheritance.
Unless the body uses "this", of course.
The body of what? Do you mean the outer function?
I'm sure I don't know what you mean.
good
There's not much point in collecting literals.
I guess I need to introduce some symbol to denote "anything
technically possible to use as a function argument". Please read "a
lot of data" as such symbol
By using the nested function expression we have created a closure for
the entire context of MyObject as it was at the end of each particular
call - and we have created as many of such closures as the amount of
object instances. Each MyObject instance will have its own copy of "a
lot of data" moreover retained by two references: by named argument
"data" and by automatically created arguments[0].
I'd have to re-read the treadment of literal strings in the specs
again to be sure about this case, but I'm quite sure that passing an
object literal doesn't necessarily mean it gets copied.
In this case your understanding of the nature of the closure is not
full so far. Again, in my sample "a lot of data" doesn't necessary
mean a string literal "a lot of data". _Anything_ being stoke in a
closure never released unless manually cleared out. This is why once a
while ago I said that using closures is like sending Devil to do the
job. It may do exactly what you want but the price may be high and the
most unexpected one.
A "contract" to think over at your spare time:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<title>Proto : 1</title>
<script type="text/javascript">
function MyObject(data) {
this.propertyOne = function(){
eval("window.alert(data)");
};
}
var obj = [1,2,3];
var myInstance = new MyObject(obj);
var obj = null;
window.setTimeout("myInstance.propertyOne()",1000);
</script>
</head>
<body>
<p>No content</p>
</body>
In fact, a
reasonably smart compiler/interpreter should see that no variables are
captured by your function(){} "closure" just by static
analysis. That's one of good points of lexical scoping.
Again, your understanding of _documented_ and expected closure
mechanics in Javascript needs more improvement.
Browsers suck. IE is just the most feckless of all the current
browsers. FTR, today's firefox 3 sucks ass too.
The world sucks for a starter
But we have to deal with it as it
is.