> 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...

I'm glad to say that this is no longer true as of the 5th edition
spec[1]. There is now the `Object.create` function defined in section
15.2.3.5 which does exactly that: Creates an object and directly sets
its prototype. (I expect Douglas Crockford was a driving force behind
that; he's been advocating this[2] for years.)

On implementations that don't have it yet, you can implement this
yourself with a workaround. It's presumably a lot less efficient to do
so, but in the absense of the native support, you can do this (also on
Pastie[3]):
* * * *
if (!Object.create) {
    Object.create = (function() {

        function Object_create(proto, props) {
            var obj, key;

            // Use a 'creator' function to create the object and
            // assign the prototype indirectly
            function creator() { }
            creator.prototype = proto;
            obj = new creator();

            // Fix the constructor reference to point to Object,
getting
            // 'creator' out of the mix (not that it was doing any
real harm)
            obj.constructor = Object;

            // Assign any properties if given
            if (typeof props === 'object') {
                for (key in props) {
                    if (props.hasOwnProperty(key)) {
                        obj[key] = props[key];
                    }
                }
            }

            // Done
            return obj;
        }

        return Object_create;
    })();
}
* * * *

That does (essentially) what the spec says the new `Object.create`
does, indirectly through a temporary constructor function.

[1] http://www.ecma-international.org/publications/standards/Ecma-262.htm
[2] http://javascript.crockford.com/prototypal.html
[3] http://pastie.org/955082

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

On May 5, 3:26 pm, "T.J. Crowder" <[email protected]> wrote:
> 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 / comwww.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...
>
> read more »

-- 
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