Fox <dont@spam.com> writes:
[color=blue]
> Lasse Reichstein Nielsen wrote:[/color]
[color=blue]
> I think you confuse the method 'prototype' with the abstract concept of
> "a prototype" or the definition of the constructor function.[/color]
There is no method called "prototype" (where I use "method" to mean
"is a property of an object and is a function").
Are you thinking about the "prototype" property of functions?
[color=blue]
> To quote Netscape documentation:
>
> "You can use the prototype to add properties or methods to all instances
> of a class."[/color]
I disagree with the way it is written. For one thing, I don't like to use
the word "class" about a objects in a prototype base language. But, for
now, let's use the word "class" about a constructor (i.e., a function)
and "instance of a class" about the objects that satsify "obj instanceof
classFunction").
[color=blue]
> Oh -- and Object IS an object and it CAN be prototyped (as in, having
> functionality added):[/color]
The global constructor "Object" is a function, and as such an object.
If you treat it as a constructor (a "class"), you can add properties
to its instances by adding properties to its prototype object.
I take it that is what you mean by "be prototyped".
That does not add functionality to Object, but only to its instances.
(So, I'm arguing that your way of saying it is imprecise, although
your meaning is probably correct)
....[color=blue]
> something() is automatically inherited by EVERY instantiated object (and
> object literal) after prototyping...[/color]
Yes. It becomes a property of the original object prototype, which is in
the prototype chain of all language objects.
[color=blue]
> this is interesting:
>
> Math.something() will display an alert [object Math] this is
> something... (Not navigator or history, though, or any other object
> "constructed" before the prototyping [like DOM objects]).[/color]
I think that is merely because the objects referenced by "navigator",
"history", and the DOM Nodes are host objects, which don't
(necessarily) have the original object prototype in their prototype
chain.
All language objects will have "something" as an inherited method,
also those created before.
Try:
---
function something() {alert (this + " is something!");}
var x = new String("foo"); // or just the equivalent, var x = {};
var d = document.createElement("div"):
alert(typeof x.something);
alert(typeof d.something);
Object.prototype.something = something;
alert(typeof x.something); // old object
alert(typeof d.something); // old host object
var x = new String("foo"){
var d = document.createElement("div"):
alert(typeof x.something); // new object
alert(typeof d.something); // new host object
---
In IE, the DOM div node will never have something as a property.
In Opera 7, it does inherit from Object.prototype, so it seems it
is browser dependent how host objects behave.
[color=blue]
> Math is a static class -- it has no constructor.[/color]
There are no classes in a prototype based language. If we use the name
"class" for functions that are used as constructors, then that's just
words to make us happy. There is definitly no such thing as a "static
class". Math is an *object*. Nothing more, nothing less. There is no
significant difference between Math and any object with the same properties.
---
var Math2 = new Object;
for(var i in Math) {Math2[i]=Math[i];}
---
That gives you a new "Math" object with exactly the same properties as
the old one. The only difference is that some of the properties of Math
are read-only, but it is still just an object.
[color=blue]
> It also has no prototype method... you cannot:[/color]
There is no prototype "method".
[color=blue]
> Math.prototype.something[/color]
No, because "Math" refers to a non-function object.
All functions have a prototype property. Non-function objects don't.
Nothing to do with classes.
[color=blue]
> which is what I meant in my original statement.[/color]
Yes. It has no "prototype" property. Nor does Math2.
[color=blue]
> Both are static classes...no constructors...[I believe there are also
> some "locks" on these, particularly history because of security concerns][/color]
Both are objects. No more, no less (host objects, though, so they can act
different from language objects).
[color=blue][color=green]
>> Because it isn't. There is no Math.prototype, because Math is not
>> a function. It is an object.[/color]
>[/color]
[color=blue][color=green]
>> What *is* prototyping to you?[/color]
>
> Just as the documentation has defined it:
> to add properties or methods to all instances of a class[/color]
Ok, that was what I thought.
Math is not a class (there is no such thing as a static class). SO,
it cannot be prototyped (apart from prototyping the Object class).
[color=blue][color=green]
>> To me, a prototype based object oriented language (as opposed to a class
>> based one) distinguishes itself in the way new objects are created.[/color]
>
> No it doesn't... nothing distinguishing about it... it's just a
> different approach -- the constructor IS the "class".[/color]
I disagree. I think that is an attempt to make a non-class based language
fit into a class based perception.
[color=blue][color=green]
>> In a class based language, new instances are based on a class.
>> In a prototype based language, new instances are based on an object.[/color]
>
> so far, the only difference is the use of the keyword "class" and an
> internal constructor in a class, and the lack of one in a
> prototyped-based OO language.[/color]
If classes are objects, yes.
[color=blue]
> in a class-based language, new instances are objects -- storage is
> allocated -- properties initialized -- methods placed in a "pool" (they
> will not be declared again -- they are shared amongst all instances of
> the class)[/color]
That is an implementation method. It is not necessarily the only one,
but it has shown itself to be efficient.
At the conceptual level, the methods are properties of the object
just as fields are.
[color=blue]
> in a prototype-based language: new instances are objects -- storage is
> allocated -- properties initialized -- methods placed in a pool
> [supposedly] (they will not be declared again -- they are shared amongst
> all instances of the main constructor -- whatever that might be at a
> given time).[/color]
In Javascript, methods are no different from other properties. No pool,
just a reference from the object.
Ok. The reason I don't think it is correct to associate the constructor
to the "class" is that whether an object is an instance of a constructor
function can change.
Example:
---
function Foo(){}
var f = new Foo();
Foo.prototype = new Object();
alert(f instanceof Foo);
---
This alerts "false"!
The object in "f" was created with "new Foo()", but still it is not an
instance of "Foo".
The constructor doesn't define the "class"! The *prototype object* of
the constructor, at the time the object is created, defines the class.
Example:
---
function Foo(){} // Constructor Foo
function Bar(){} // Constructor Bar
var f = new Foo();
var b = new Bar();
var oldFooProt = Foo.prototype;
Foo.prototype = Bar.prototype;
var fb = new Foo();
Foo.prototype = oldFooProt;
// now guess the result of:
alert([f instanceof Foo,f instanceof Bar])
alert([b instanceof Foo,b instanceof Bar])
alert([fb instanceof Foo,fb instanceof Bar])
---
Here "fb" is created from the constructor "Foo", but it is an instance
of the (almost) unrelated constructor "Bar". Why? Because Bar's prototype
property refers to an object that is in fb's prototype chain.
The constructor doesn't define the class. The prototype object does.
That is what I mean by the difference between class based and
prototype based languages.
In a class based language, the class (object/definition) defines the
instances of the class.
In a prototype based language, any object defines a "class" of the
objects that are instances of it.
Javascript attempts to hide this using constructor functions, but
that's just wrapper. What really goes on below is inheritance between
an object (the prototype object of the constructor at the time) and
a new object. The constructor itself is just some function that is
not related to the inheritance. It's just a language gimmick to
enable prototype-inheritance between objects.
The clone method I previously posted would also work in general:
---
Object.prototype.clone = function(){
function nop(){}; // dummy function to facilitate inheritance
nop.prototype = this;
return new nop();
}
Object.prototype.instanceOf = function (obj) {
function nop(){};
nop.prototype = obj;
return this instanceof nop;
}
var rootObject = Object.prototype;
---
Then you can write:
---
var o1 = rootObject.clone(); // new object
var o2 = rootObject.clone(); // new object
var o3 = o1.clone(); // new instance of first object
o1.foo = 42; // extend first object/prototype of third
alert([o3.foo, o3.instanceOf(o1), o3.instanceOf(o2)]);
---
That is pure prototype based object oriented programming (I believe it
is closer to how it is done in the language Self). As you can see, the
actual constructor functions are irrelevant, inheritance still works,
instanceOf works, all because the actual prototype inheritance happens
between the *objects*. The constructors, the "classes", are just
scaffolds for the actual construction of objects.
[color=blue][color=green]
>> There is only one Math object, so that is completely unnecessary.[/color]
>
> There is only one String object, one Number object, one Array object,
> etc... and yet, prototype is a method of those objects... it is
> unnecessary because Math is not intended to be instantiated... but that
> doesn't mean that, for consistency, it couldn't be used syntactically in
> the same manner as these other core objects.[/color]
Except that it makes little sense to create more than one Math object,
since none of the "methods" operate on the object. You are correct that
one would most likely create Math as a static class in a class based
language, but that is because the class based language lacks a better
way to create a namespace - which is what you really want. In Standard
ML, it would be a module, which is just a namespace that can be opened
or accessed. In Javascript, it is an object, which is slightly more than
just a mapping from name to values.
[color=blue][color=green]
>> The "standard" way (if any such exist) to add properties to an
>> object, is by assigning it directly to the object.[/color]
>
> poor programming habits are rampant in JS programmers. The FAQ uses
> prototype where appropriate (and correctly), not that I would tout the
> faq as a guideline for programming style convention. However, that
> flexibility exists, and it is anyone's prerogative to do so. In the case
> of Math, it is a necessity.[/color]
Adding a property to the prototype of a number of instances saves space
compared to adding it to each (and adds flexibility to change it later).
Adding a property to one object is best done by adding it directly to
the object.
I don't think you can generalize and say that one is always better than
the other. It depends on the actual case.
[color=blue][color=green][color=darkred]
>> > I can be pretty dense sometimes -- I don't get this question. What else
>> > *can* I do?[/color]
>>
>> Ok, why do you want to do it differently?[/color]
>
> Do what differently? that section didn't make any sense to me.[/color]
And I cut the context, so I can't remember what I was replying to.
Damn! It made sense when I wrote it.
[color=blue]
> I was wrong (I'm tired and stressed)... I meant 96-bit long doubles that
> are available in C (at least in some compilers). It's been several years
> since I've worked in C, so... I had to go back and look it
> up...something I should have done before i made the statement.[/color]
Numbers get awfully big. I too remember when 16 bit computers were a
fantastic progress :)
/L
--
Lasse Reichstein Nielsen -
lrn@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'