Hi,

Javascript is *all* about object orientation, not procedural
programming (programming with functions not grouped into objects, like
C). The statement that Javascript functions are "first-class objects"
refers to the fact that they're real objects, not just a compiler or
interpreter construct, and can be used like any other object.

Javascript's object orientation is natively prototypical rather than
class-based (although I think it's really a bit of a hybrid).
Prototype's `Class` object and its methods don't really create
classes; they just make it easier for people with a class-based
background to access prototypical inheritance without having to go
through the learning curve and paradigm shift involved. And even once
you've been through the paradigm shift, they're still handy because of
all the plumbing they do for you.

So I'd say: Keep using `Class`, but at the same time, find a really
good book on prototypical inheritance and work your way through it so
you know what you're really dealing with. This article[1] from Douglas
Crockford may be useful as well, but be forewarned that Crockford is
heavy going for someone relatively new to Javascript. :-)

A bit (hah!) more detail:

In a prototypical system, an object is backed by a "prototype" object
that gives it its default properties (including properties that are
functions). The object itself starts out blank, but it doesn't *seem*
blank because if you retrieve a property from it and it doesn't have
its own property by that name, the interpreter will look at the
prototype object and see if it has the property -- and so on up the
prototype chain.

This is a lot simpler than it sounds. Let's look at an example: Let's
assume we have this object:

   var A = {
     x: "ecks"
   };

`A` has one property: `x`, with the value "ecks". Now, let's assume we
have an object `B` that we've created in such a way that `A` is its
prototype (details on that later):

    var B = /* hand waving here, create object and make `A` its
prototype */;

Now we can do this:

    alert(B.x); // alerts "ecks"

`B` doesn't have a property called `x`, but it does have a prtotype
(`A`) that does, and so the interpeter uses that. Let's give `B` a
property of its own:

    B.y = "why";

Now we can do this:

    alert(B.x); // alerts "ecks" (from the prototype `A`)
    alert(B.y); // alerts "why" (from `B` itself)

Now let's change `x`:

    B.x = "X";

Now `B` has its *own* property called `x`, so:

    alert(B.x); // alerts "X" (from `B` itself)
    alert(B.y); // alerts "why" (from `B` itself)

`A` hasn't been changed at all (changes to `B` change `B`, not `A`).

Now, note that while `A` is `B`'s prototype, `A` has a prototype of
its own. When you access a property on an object, the interpreter may
look through an entire chain of objects (the "prototype chain") to
satisfy that request. (But good implementations do that really, really
quickly.)

Contrast this with class-based systems. In a class-based system, the
object instance itself is shallow -- it holds all of its own data.
Default values assigned by the constructor are *copied* to the
instance during construction, not inherited. Only methods are
inherited, through compiler/interpreter constructs rather than first-
class objects we can directly manipulate.

Speaking of methods: An object can inherit functions from its
prototype in *exactly* the same way `B` inherited `x` from `A` above:

    var A = {
        foo: function() {
            alert("A's foo!");
        }
    };

    var B = /* hand waving here, create object and make `A` its
prototype */;

    B.foo(); // alerts "A's foo!" (using `A`'s `foo` property)

But just as with `x`, we could change that if we wanted:

    B.foo = function() {
        alert("B's foo!");
    };

    B.foo(); // alerts "B's foo!" (using `B`'s `foo` property)

There is *no* difference between a property whose value is a function
and a property whose value is a string, or a number, or anything else.

About the hand waving: Most prototypical languages make the object's
prototype directly accessible (as a psuedo-property of the object).
Javascript doesn't. There's no property you can grab to tell you what
the object's prototype is, and no way to assign a new prototype to an
existing object. The way in which Javascript assigns a prototype to an
object is very unusual for a prototypical language: It can only be
done (barring implementations that go beyond the spec) by constructing
the object via a constructor function -- and doing it that way is
*very* class-like. Hence my comment about Javascript being a bit of a
hybrid. Let's look at that:

All functions in Javascript have a property called `prototype`:

    function Foo() {
    }
    alert(typeof Foo.prototype); // alerts "object"

...but most of them never use it for anything. It only comes into play
when you start using the function as a "constructor function" (by
calling it via the `new` operator). When you do that, a new object is
created and its prototype (that thing we can't access directly) is set
to the function's `prototype` property (and then the function is
called with `this` referencing the new object):

    function Foo() {
    }
    Foo.prototype.x = "ecks";

    var f = new Foo();
    alert(f.x); // alerts "ecks", via the `Foo.prototype` object that
backs `f`

It would be easy to get confused here, so just reiterating: You cannot
access (either get or set) the prototype of an object directly.
Functions have a property called `prototype`, but that is NOT the
function's prototype, it's the object that will be used as the
prototype for new objects created when you use that function as a
constructor function via `new`.

The `prototype` property on a function instance is a property just
like any other property; its default value is an (effectively) blank
object. You can add properties to that blank object (as we did above)
just like you can add properties to any other object. You can even
completely replace its value with a new object if you like, but
assigning to it like any other property:

    Foo.prototype = {
        x: "ecks",
        glarb: function() {
            // ...
        }
    };

This is the basis for prototypical inheritance in Javascript, and it's
what Prototype (big P) uses behind the scenes in its `Class` stuff.

Getting back to functions being first-class objects: They are indeed
exactly that. They're objects with this special ability to represent
code that can be executed (and a context for executing it). This is a
very important concept, and a powerful one, that can easily be
misunderstood. Here[2] are[3] a couple of articles[4] on my blog that
may help a bit (or may just confuse matters).

Two quick (hah!) final notes about not being able to access the
prototype of an object directly:

1. Some implementations (Firefox's Javascript engine SpiderMonkey, for
instance) let you do that, via a psuedo-property called __proto__.
This is not in the Javascript specification (not even the new one,
although it was considered).

2. Some people will tell you that you can get there by looking at
`obj.constructor.prototype`. This is because when you create an
object, its `constructor` property is set to the function that
constructed it, and of course as you know the constructor function's
`prototype` property contains the prototype it assigns to objects when
you use `new` with it. Problem solved? No. Consider:

    function Foo() {
    }
    Foo.prototype.x = "ecks";

    var f1 = new Foo();

    Foo.prototype = {
        x: "X"
    };

    var f2 = new Foo();

    alert(f1.x);
    alert(f2.x);

What does the first alert show? The second? You could be forgiven for
assuming they would both show the same thing, "X", but they don't --
because `f1` was assigned `Foo`'s first prototype object, but then
that object was *completely replaced* before `f2` was created. So `f1`
and `f2` have the same constructor function, but different prototypes.
`f1.constructor.prototype` does refer to an object, but that object is
not `f1`'s prototype (anymore). This is one of the reasons I don't
recommend actually *replacing* a function's prototype unless you're
doing it on purpose for exactly this reason.

[1] http://javascript.crockford.com/prototypal.html
[2] http://blog.niftysnippets.org/2008/03/mythical-methods.html
[3] http://blog.niftysnippets.org/2008/04/you-must-remember-this.html
[4] http://blog.niftysnippets.org/2008/02/closures-are-not-complicated.html

HTH,
--
T.J. Crowder
Independent Software Consultant
tj / crowder software / com
www.crowdersoftware.com


On May 5, 12:06 pm, Hari <[email protected]> wrote:
> Hi,
>
> One of the best features I like about prototype is support for OO
> support.
>
> It helps me to group the functions and properties in a logical
> structure using Class and also maintain it. But some people pointed
> out that JavaScript programming was not meant to be programmed in
> terms of classes and objects, instead in terms of functions. If I
> start thinking in terms of OO then I forget the concept of first class
> functions(functions which can exist without any class), but JS is
> supposed to programmed considering functions as first class elements
> (I haven't worked on any functional programming language before).
>
> Should I continue my OO approach or should I start appreciating JS as
> functional programming language and learn? Any comments on this topic
> would be helpful
>
> Thanks and Regards,
> Hari
>
> --
> You received this message because you are subscribed to the Google Groups 
> "Prototype & script.aculo.us" group.
> To post to this group, send email to [email protected].
> To unsubscribe from this group, send email to 
> [email protected].
> For more options, visit this group 
> athttp://groups.google.com/group/prototype-scriptaculous?hl=en.

-- 
You received this message because you are subscribed to the Google Groups 
"Prototype & script.aculo.us" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/prototype-scriptaculous?hl=en.

Reply via email to