Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Why I still prefer Prototype to jQuery (thinkrelevance.com)
67 points by luccastera on Jan 12, 2009 | hide | past | favorite | 22 comments


Not having extensively used either jQuery or Prototype, I found this comparison interesting. But the entire discussion about jQuery "stealing" `this` is somewhat misinformed. Javascript closures don't caputure the value of `this`; instead, the value of `this` is determined at the call site. If the function is called as a method (using the `object.method()` syntax), `this` is bound to `object`; otherwise, `this` is bound to the global object (called `window` in browsers). The behavior I just described makes `this` is almost useless in Javascript closures, and the "idiomatic Prototype" example the author gives cannot possibly work:

    // Prototype
    $A(this.columns).each(function(item) {
        this.buildHeader(item);
    });
If you want to do that, you have explicitly bind `this` to a (differently named) variable in the outer scope:

    var self = this;
    $A(self.columns).each(function(item) {
        self.buildHeader(item);
    });


I will say this, use of this is very scary and requires me to look at the docs more often (need to know where in the scope chain this is being set).

In fact, I'd argue that in general seeing uses of this outside of object oriented code make me sit up and look very carefully, because its really easy to get spooky "action at a distance" type behaviour.


Or pass in an object to the function that will be bound to this.

$A(self.columns).each(function(item) { this.buildHeader(item); }, this);

In general I prefer the technique you described as it is the most frequent use case and simplifies the implementation of the function that executes the callback.


or you can use javascript call or apply

  method.call (<object you want to be *this*>, params);


>> "The behavior I just described makes `this` is almost useless in Javascript closures"

Hmm??

e.onmouseover = function(c) {return function() { c.dosomething()}}(this);

Then in the dosomething function, "this" references what you expect...

I don't see why you need a library to construct a simple closure.


Note how you haven't used the keyword `this` inside the closure. What you've written is functionally equivalent to the technique I described, assigning the `this` object to a temporary variable. The only difference is that you bind it with a lambda instead of a `var`.


I don't use the keyword this inside the closure, but inside the function dosomething() I can happily use "this".


I don't understand why does one need to make a choice. Even comparing the two makes little sense: jQuery is smaller and DOM-focused, while Prototype is a much more comprehensive multi-file library and DOM-related stuff is just a part of it, completely isolated in its own file which you can exclude during Prototype's build process.

I use both: jQuery for HTTP and DOM traversing/manipulation plus DOM-less prototype core for everything else. This combo is awesome, conflict-free and quite compact when gzipped. Bare bone JavaScript is too weak library wise and Prototype makes an excellent "standard library" for it. I couldn't live without Prototype's extensions to enumerable, strings, arrays, hashes, etc.

And it's 100% compatible with Rails thanks to jRails project. I highly recommend it.


One argument against doing both is that Prototype alters many built in classes directly. This is often risky and dangerous, and makes interactions between the two code bases possible.


Prototype alters stuff but jQuery doesn't. So there is very little conflict. The use of Prototype however will prevent use of other altering js frameworks like MooTools.

Fundamentally I think Prototype/MooTools are horribly designed javascript library because they introduce incompatibilities. However I use them when I need a free component or 2. I would never drop jQuery though so I always use $j instead of $, even when using jquery by itself


A correction: it's better to say "Prototype expands built-in classes", i.e. it adds methods that otherwise aren't there. This is never risky nor dangerous unless you have another global-namespace library, which jQuery isn't.


    Determine the index of the first parameter in the Array …
    Ah, it returns the index. But that’s OK … JavaScript supports the notion of “truthiness”,
Except if it returns "0", of course.

It's a very C-like way of doing things:

   if ($.inArray(blah blah) < 0)
        // not found!


It's nice to see a level-headed assessment like this. Too many programmers rely on trends or religious convictions to make decisions. All choices involve trade-offs, so make yourself aware of them!


it is true that all choices involve trade-offs, and one library is going to likely be "best" for you based on your individual needs.

but i wouldn't call this article level-headed, it has an explicitly stated tilt towards prototype.


JavaScript 1.6 added seven new array methods (indexOf, lastIndexOf, every, filter, forEach, map, and some). If only backward compatibility weren't a problem, the warring JavaScript libraries could just use these (or implement them into the prototype like Sugar Arrays, http://www.dustindiaz.com/sugar-arrays/) instead of creating their own quirky methods.


The Prototype this example won't work unless this is bound to the anonymous function, otherwise this is the window object.

  $A(this.columns).each(function(item) {
    this.buildHeader(item);
  }.bind(this));


Based on the use of "this.columns" I assume this is bound to something. Probably not the anonymous function though.


I don't have a huge amount of experience with either framework, but I've used them both. One thing that stands out about jQuery is that it's unobtrusive - Prototype is not (at least not without some help from something like Lowpro).


One of his arguments was that prototype is not that slow anymore in comparison to jQuery.

Some nice speed improvements are coming to jQuery 1.3:

http://www.flickr.com/photos/jeresig/sets/72157612498756067/


jQuery is light, but it has a trove of plugins that will help you with more complex tasks. The core is purposefully limited in scope, not trying to do everything for you; it only provides what Javascript already should, but doesn't.


i prefer framework that helps me crafting shorter code

the last time i used prototype was in 2007, now it's all jquery


Argument order:

jQuery

$.each(collection,function(){ this.bla(); });

The reason index is first param is because wheb you need it it is the only param. The reason for the item param is incase you need to attach a scope object to be this!




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: