From ebb31e4ef4c1ac336d805ea4f8fd44d8a85ffa8a Mon Sep 17 00:00:00 2001 From: Ivan Ivanov Date: Sun, 19 Aug 2012 19:07:08 +0400 Subject: [PATCH 1/8] Copied index.html to create a russian translation --- index_ru.html | 922 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 922 insertions(+) create mode 100644 index_ru.html diff --git a/index_ru.html b/index_ru.html new file mode 100644 index 0000000..f986717 --- /dev/null +++ b/index_ru.html @@ -0,0 +1,922 @@ + + + + + jQuery vs MooTools: Choosing Between Two Great JavaScript Frameworks + + + + + + + + + + + + + + + +
+ +

jQuery vs MooTools

+ +

+ Most people getting started with JavaScript these days are faced with the challenging task of picking a library to use, or at least which one to learn first. If you're working for a company chances are they have already chosen a framework for you, in which case the point is somewhat moot. If this is the case and they've chosen MooTools and you're used to jQuery, then this article might still be of some use to you. +

+

+ Every day on twitter I see numerous posts that boil down to "MooTools or jQuery?" This article aims to help you make that choice. +

+

Disclaimer

+

+ I am a MooTools developer. I work on the MooTools framework. I blog about MooTools. I wrote the main online tutorial and the book about MooTools. Obviously, I have a perspective that is somewhat biased. I'll also point out that I don't use jQuery that often. If you're a jQuery developer and see anything that I have misrepresented here, please contact me and help me rectify the issue. My objective here is to be helpful and accurate to people - not to sell one framework over another. +

+ +

Purpose

+

+ Helping you make a choice between these two frameworks involves me telling you how they are different. I'll start out by saying that both of them are excellent choices. You can't make a wrong choice here. Both frameworks have their strengths and weaknesses, but, in general, they are both great choices. There are other frameworks out there that are worth digging into as well. Dojo, Prototype, YUI, Ext and others are all great choices. Which one you choose really has more to do with your own style and what you need to accomplish. The purpose of this article is to focus on MooTools and jQuery, as increasingly these are the two frameworks that I see a lot of people considering. Finally, I'm not trying to convince anyone to switch from one framework to the other. There are interesting things about both frameworks from which you can learn. You can read a little more about this article and why I wrote it in my blog post on Clientcide where I announced it. +

+ +

Table o' Contents

+ + +

The Stats

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
jQuery CoreMooTools Core
Library Size55.9K64.3K
Features
LicenseMIT & GPLMIT
DOM Utilitesyesyes
Animationyesyes
Event Handlingyesyes
CSS3 Selectorsyes (a subset)yes (a subset)
Ajaxyesyes
Native Extensions (excluding Element)about a dozen for Array, Object, and Stringabout six dozen for Array, Object, String, Function, and Number
InheritanceNot supported directly with jQueryProvided with Class constructor
Other Considerations
plug-insHundreds of unofficial plug-ins in a directory at plugins.jquery.comRoughly 4 dozen official plug-ins available at mootools.net/more. Unofficial plugin directory at mootools.net/plugins.
Official UI libraryyesno
+

+ Information based on data from jquery.com, mootools.net, and wikipedia.com. +

+ + +

The Mottos Say It All

+ + +

+ If you go to the jQuery site, here's what it says at the top of the page: +

+
jQuery is a fast and concise JavaScript Library that simplifies HTML document traversing, event handling, animating, and Ajax interactions for rapid web development. jQuery is designed to change the way that you write JavaScript.
+

+ ...and if you go to MooTools, this is what you'll find: +

+
MooTools is a compact, modular, Object-Oriented JavaScript framework designed for the intermediate to advanced JavaScript developer. It allows you to write powerful, flexible, and cross-browser code with its elegant, well documented, and coherent API.
+

+ I think this really sums it up. If you ask me (and you're reading this, so I'll assume you just have), the question isn't about which framework is better or worse. It's which one of these things above do you want to do? These two frameworks just aren't trying to do the same things. They overlap in the functionality they provide, but they are not trying to do the same things. +

+ +

+ jQuery's description of itself talks about HTML, events, animations, Ajax, and web development. MooTools talks about object oriented-ness and writing powerful and flexible code. jQuery aspires to "change the way you write JavaScript" while MooTools is designed for the intermediate to advanced JavaScript developer. +

+ +

+ Part of this consideration is the notion of a framework vs a toolkit. MooTools is a framework that attempts to implement JavaScript as it should be (according to MooTools' authors). The aim is to implement an API that feels like JavaScript and enhances everything; not just the DOM. jQuery is a toolkit that gives you an easy to use collection of methods in a self-contained system designed to make the DOM itself more pleasant. It just so happens that the DOM is where most people focus their effort when writing JavaScript, so in many cases, jQuery is all you need. +

+

+ Most of the code you write when you write MooTools still feels like JavaScript. If you aren't interested in JavaScript as a language, then learning MooTools is going to feel like a chore. If you are interested in JavaScript and what makes it interesting, powerful, and expressive, then, personally, I think MooTools is the better choice. +

+ + + +

The Learning Curve and The Community

+ +

+ First, jQuery is, by and large, easier to learn. It has an almost colloquial style that almost doesn't feel like programming. If all you want is to get something working quickly without learning JavaScript, jQuery is probably a better choice for you. It's not that MooTools can't help you accomplish the same things, but I'll admit that MooTools can be a little harder to get the hang of if you're new to JavaScript and also that there are just a lot of resources out there to help you learn jQuery - more than there are for MooTools at least. +

+ +

+ If you compare the jQuery community (see the "Discussion" page on jQuery) and the MooTools community (irc, mailing list, and unofficial forum) you'll quickly discover two things: 1) the jQuery community is far larger (I attribute this mostly to the point I made above about how easy it is to learn, but also because...) and 2) they are more active in promoting the library. If you measure jQuery and MooTools on metrics like the number of people using it, the number of search queries run on Google, the number of books sold, etc, you'll see jQuery is ahead by a wide margin. +

+ +

+ To tell you why you might consider MooTools I'll first need to talk a little bit about what both the frameworks do. Ultimately which framework you choose is going to come down to what you want to accomplish and how you like to program (and maybe even if you like to program, at least in JavaScript). +

+ + +

What JavaScript Is Good For

+ +

+ Part of making this choice is asking what you want to do with JavaScript. Let's consider vanilla JavaScript. No framework; just plain old JS. JavaScript gives you native objects like Strings, Numbers, Functions, Arrays, Dates, Regular Expressions, and more. JavaScript also gives you an inheritance model - a somewhat esoteric model called prototypal inheritance (which I'll talk about more later). These building blocks and the concept of inheritance are the bread and butter of any programming language and they have absolutely nothing to do with browsers or the web or CSS or HTML. You could write anything you wanted to in JavaScript. Tic-tac-toe, chess, photoediting, a web server, whatever. It just so happens that 99% of all the JavaScript out there is run in browsers and that's what we think of it as. The programming language for browsers. +

+

+ Understanding that the browser, the DOM, is just where we happen to use JS most of the time but that it's actually a very robust and expressive programming language will help you understand the difference between MooTools and jQuery. +

+ + +

More Than Just The DOM

+ +

+ If you think of the tasks that we want to accomplish in JavaScript strictly in terms of "get stuff on the page and do stuff to it" then jQuery is probably the best choice. It excels at offering a very expressive system for describing behavior on the page in a way that doesn't feel like programming sometimes. You can still use the rest of JavaScript to do what you want to do, but if you're focused on the DOM - changing CSS properties, animating things, fetching content via AJAX, etc - most of what you'll end up writing will be covered by jQuery, and what isn't will likely be plain-old JavaScript. jQuery does provide some methods that aren't about the DOM; for example, it provides a mechanism for iterating over arrays - $.each(array, fn) - or, for example, it offers a trim method for strings - $.trim(str). But there aren't a ton of these types of utility methods, which is fine because, for the most part, if you're just getting stuff out of the DOM, iterating over them, and altering them in some way (adding html, changing styles, adding event listeners for click and mouseover, etc) you don't need much else. +

+

+ But if you think of JavaScript's scope in its full breadth, you can see that jQuery doesn't focus on things outside of the DOM. This is one of the reasons it is so easy to learn, but it also limits the ways it can help you write JavaScript. It's just not trying to be anything other than a solid programming system for the DOM. It doesn't address inheritance nor does it address the basic utilities of all the native types in the JavaScript language, but it doesn't need to. If you want to mess around with strings, dates, regular expressions, arrays and functions, you can. It's just not jQuery's job to help you do it. JavaScript as a language is there at your feet. jQuery makes the DOM your playground, but the rest of JavaScript is just not in its scope. +

+

+ This is where MooTools is vastly different. Rather than focusing exclusively on the DOM (though, as I'll get into in a bit, it offers all the functionality that jQuery does but accomplishes this in a very different manner), MooTools takes into its scope the entire language. If jQuery makes the DOM your playground, MooTools aims to make JavaScript your playground, and this is one of the reasons why it's harder to learn. +

+ + +

Inheritance with JavaScript

+ +

+ The JavaScript programming language has some really awesome things about it. For starters, it's a functional language, which means that it treats functions as high-order objects that can be passed around as variables just like any other object - strings or numbers for example. It's designed with this concept in mind and many of the methods and patterns in it work best when you write code this way. It's the difference between: +

+
for (var i = 0; i < myArray.length; i++) { /* do stuff */ }
+

+ and +

+
myArray.forEach(function(item, index) { /* do stuff */ });
+

+ JavaScript has an inheritance model that is not quite unique but at least rather rare in programming languages. Instead of classes that are defined that can be subclassed it passes along traits through prototypal inheritance. This means that objects inherit directly from other objects. If you reference a property on an object that inherits from another object, the language inspects the child object for that property and, if it doesn't find it, looks for it on the parent. This is how a method on, say, an array works. When you type: +

+
[1,2,3].forEach(function(item) { alert(item) }); //this alerts 1 then 2 then 3
+

+ the method "forEach" is not a property of the array you declare ([1,2,3]), it is a property of the prototype for all Arrays. When you reference this method the language looks for a method called forEach on your array, and, not finding it, then looks at the prototype for all arrays. This means that the forEach method is not in memory once for every array in memory; it is only in memory for the prototype of arrays. This is incredibly efficient and ultimately quite powerful. (Side note: MooTools aliases the forEach method as each) +

+ + +

Self Reference

+

+ Javascript has a special word: "this". It's hard for me to succinctly define what "this" is all about but, by default, "this" is the object to which the current method belongs. It allows objects to refer to themselves within their methods as they would otherwise have no means to do so. This becomes important when you create children objects and have numerous instances of that object; how else could the method of an object refer to itself? When the actual copy of the method exists on the parent, not the child, the "this" keyword allows these instances to refer to their own state. (here's a much more complete description of the "this" keyword, and another from Mozilla.) +

+

+ The "this" keyword allows objects that inherit from other objects to refer to themselves, but there are times when you may want to reference something else through "this". This is called binding, wherein you specify a different "this" for a method. The "each" method on Array allows you to specify the bound object with a second argument. Here's an example of where you might want to pass in a different "this": +

+
var ninja = {
+    weapons: ['katana', 'throwing stars', 'exploding palm technique'],
+    log: function(message) {
+        console.log(message);
+    },
+    logInventory: function() {
+        this.weapons.each(function(weapon) {
+			//we want "this" to point to ninja...
+            this.log('this ninja can kill with its ' + weapon);
+        }, this); //so we pass "this" (which is ninja) to Array.each  
+    }
+};
+ninja.logInventory(); 
+//this ninja can kill with its katana
+//this ninja can kill with its throwing stars
+//this ninja can kill with its exploding palm technique
+ +

+ In the example above, we bind ninja (which is "this" inside the logInventory method) to the method we pass to the array so that we can refer to the log property of ninja. If we didn't do this, "this" would be window. +

+

+ These are just some examples of the power and expressiveness that JavaScript has to offer - inheritance, self reference and binding, and efficient prototype properties. The bad news is that vanilla JavaScript doesn't make these powerful things very useful or accessible, and this is where MooTools starts. It makes these types of patterns easy and rather pleasant to use. You end up writing more abstract code, and in the long run, this is a good thing - a powerful thing. Learning how these patterns are valuable and how to use them properly takes effort, but the up side is that the code you author is both highly reusable and much easier to maintain. I'll talk about these two things a bit more in a minute. +

+ + +

MooTools Makes JavaScript Itself More Fun

+ +

+ Because MooTools focuses on making the JavaScript API itself more stable and coherent, it is focused less on giving you an interface that "changes the way you write JavaScript" and more on making JavaScript as a whole less frustrating; MooTools is an extension to the JavaScript language. MooTools tries to make JavaScript the way it is meant to be. A significant portion of the core library is spent on augmenting Function, String, Array, Number, Element and other prototypes. The other big thing it offers is a function called Class. +

+

+ Now, Class looks to many people like it's trying to recreate a more classical inheritance model that one might find in Java or C++, but that's not the case. What Class does is make the prototypal inheritance model of JavaScript easier for you and me to access and take advantage of. I'll note that these concepts are not unique to MooTools (other frameworks offer similar functionality), but both of these concepts are not present in jQuery. jQuery does not offer an inheritance system nor does it offer any enhancements to native objects (Function, String, etc). This is not a deficiency of jQuery as the authors of jQuery could easily offer these things. Rather, they have designed a toolkit with a different goal in mind. Where MooTools aims to make JavaScript more fun, jQuery aims to make the DOM more fun and its designers have chosen to limit their scope to that task. +

+ + +

jQuery Makes the DOM More Fun

+ +

+ And this is why jQuery is more accessible. It doesn't ask that you learn JavaScript inside and out. It doesn't throw you into the deep end with prototypal inheritance, binding, "this", and native prototypes. When you get started with jQuery in its official tutorial, this is the first jQuery code example you find: +

+ +
window.onload = function() {
+    alert("welcome");
+}
+ +

and here's the third:

+ +
$(document).ready(function() {
+    $("a").click(function(event) {
+        alert("Thanks for visiting!");
+    });
+});
+ +

+ If you read the MooTools book or the MooTools tutorial (both of which I authored) they start in a much different place. While you can skip ahead and quickly learn about effects and the DOM, if you want to learn MooTools, you have to start with things like Class, and, I'll admit: if you're new to programming, or you just want to get something working on your site without having to learn everything about JavaScript, chances are jQuery is going to look a lot more friendly to you. +

+ +

+ On the other hand, if you want to learn JavaScript itself, MooTools is a great way to do it. It implements a lot of things that JavaScript is going to have (many of the methods on Natives are just the JavaScript 1.8 spec and beyond). If you're used to programming, especially both object oriented and functional programming, MooTools has a lot of design patterns that are very exciting and expressive. +

+ + +

Anything You Can Do I Can Do Better

+ +

+ If you look at the things jQuery can do, there's often a counterpart in MooTools. If you look at the things MooTools can do, there is often no way to emulate it using jQuery code because of jQuery's focus on the DOM. MooTools has a broader functionality than jQuery, but there's nothing about jQuery that prevents you from doing those things. For example, jQuery does not come with any sort of inheritance system, but that's ok. You could, if you want, use the MooTools Class in conjunction with jQuery if you wanted to (or write your own). There's even an inheritance plug-in for jQuery (I haven't used it, but I assume it offers pretty much the same kind of functionality). +

+ +

If we look at the example from jQuery above:

+ +
$(document).ready(function() {
+    $("a").click(function(event) {
+        alert("Thanks for visiting!");
+    });
+});
+ +

+ and we wanted to translate this to MooTools, we'd have: +

+
window.addEvent('domready', function() {
+    $$('a').addEvent('click', function(event) {
+        alert('Thanks for visiting!');
+    });
+});
+

+ These are very similar no? +

+

+ Here's a more complex example from jQuery: +

+ +
$(document).ready(function() {
+    $("#orderedlist li:last").hover(function() {
+        $(this).addClass("green");
+    },
+    function() {
+        $(this).removeClass("green");
+    });
+});
+ +

+ and in MooTools: +

+ +
window.addEvent('domready',function() {
+    $$('#orderedlist li:last-child').addEvents({
+        mouseenter: function() {
+            this.addClass('green');
+        },
+        mouseleave: function() {
+            this.removeClass('green');
+        }
+    });
+});
+ +

+ Again, very similar. I'd argue that the MooTools version is more explicit, but also more verbose because of it. It's clear reading the MooTools code that we're adding two events - one for mouse enter and one on mouse leave, while the jQuery version is more concise; its hover method accepts two methods - the first for mouse enter and the second for mouse leave. I personally like the fact that the MooTools code is more legible but that's a very subjective observation. +

+ +

+ I will say that sometimes jQuery can become too esoteric for my taste. The methods don't always make sense to me just looking at them and I find it hard to parse. This is somewhat unfair though, as I am intimately familiar with MooTools, so reading MooTools is easy for me. But one of the things I appreciate about MooTools is how almost all the method and class names really name the thing. Methods are almost always verbs and leave little doubt as to what they do. Every programming language requires you to go to the docs to look up syntax when you write it - I'm not saying that. I'm just saying that I find the API of MooTools to be more coherent and consistent. +

+ + +

MooTools Lets You Have It Your Way

+ +

But what if you like the jQuery syntax? One way to illustrate the power of MooTools is to show you how easy it is to change it to suit your tastes. If we wanted to implement the hover method from jQuery in MooTools, we could easily do so:

+ +
Element.implement({
+    hover : function(enter,leave){
+       return this.addEvents({ mouseenter : enter, mouseleave : leave });
+    }
+});
+
+//and then you could use it exactly like the jQuery version:
+$$('#orderlist li:last').hover(function(){
+   this.addClass('green');
+},
+function(){
+   this.removeClass('green');
+});
+
+ +

Indeed, there are MooTools plug-ins that do just that; give you the jQuery syntax for MooTools. MooTools' focus on extensibility means you can implement anything you like. This is something jQuery can't do. MooTools can mimic jQuery if you want it to, but jQuery can't mimic MooTools. If you want to write classes or extend native prototypes or do some of the other things MooTools can, you'll have to write it yourself.

+ + +

Chaining as a Design Pattern

+ +

+ Let's do another of these. Here's some jQuery (from the jQuery tutorial): +

+ +
$(document).ready(function() {
+    $('#faq').find('dd').hide().end().find('dt').click(function() {
+        $(this).next().slideToggle();
+    });
+});
+ +

+ This is an example of a syntax that I personally don't prefer. Looking at the code above I am hard pressed to be sure of what it's doing. Most notably I'm curious about what .end does and how does .find, which follows it, relate to what .end does? Now, looking at the docs on jQuery makes it very clear what .end does (it resets to the value of the original selector, in this case #faq). But this seems very odd to me. When I do work with jQuery, I often find myself unsure what a method is going to return to me. Obviously this doesn't bother everyone else as jQuery has a lot of people happily using it, so I'll chalk it up to personal preference again. +

+

+ Let's look at the above logic as MooTools: +

+ +
window.addEvent('domready', function() {
+    var faq = $('faq');
+    faq.getElements('dd').hide();
+    faq.getElements('dt').addEvent('click', function() {
+        this.getNext().slide('toggle');
+    });
+});
+
+ + +

+ Again, the MooTools code is a bit more verbose, but also more explicit. Also note that the design pattern here is to store the reference to #faq in a variable, where jQuery uses its .end method to return to it. I'll note that it's possible to write highly chained code with Mootools. For example: +

+
item.getElements('input[type=checkbox]')
+	.filter(function(box) {
+		return box.checked != checked;
+	})
+	.set('checked', checked)
+	.getParent()[(checked) ? 'addClass' : 'removeClass']('checked')
+	.fireEvent((checked) ? 'check' : 'uncheck');
+ +

+ But really, writing code like this - lots of logic in a domready statement - with either framework, I'd argue, is itself a bad practice. It's far better to encapsulate your logic into reusable chunks. +

+ + +

Reusing Code with jQuery

+ +

+ It's very tempting when you're working on a web project to write code this way. Just add some logic on the page that selects the DOM elements and "sets them up" by hiding some, altering others, and adding event listeners for click or mouseover. Developing code this way is very efficient, very fast. The problem with writing all your logic in domready statements is that you end up with a lot of code that does the same thing in different places. If we take the FAQ pattern above we could easily apply the same logic elsewhere on a different page with any list of terms and definitions. Are we going to repeat the same logic every time we find this pattern? +

+

+ A simple way to make it reusable is to wrap the logic in a function and pass in arguments. Here's what that might look like in jQuery: +

+ +
function faq(container, terms, definitions) {
+    $(container).find(terms).hide().end().find(definitions).click(function() {
+        $(this).next().slideToggle();
+    });
+};
+$(document).ready(function() {
+    faq('#faq', 'dd', 'dt');
+});
+ +

+ This is much better for two really big and important reasons: +

+
    +
  1. + If tomorrow we need to change how these lists work (maybe we want to add click tracking logic so we can measure it in our web logs or maybe we want to fetch the definitions via ajax) we can just change our main faq method and everywhere we use it just gets updated. Or if there's a new version of jQuery released that changes the way things work, we can just go update our one method instead of a dozen copies everywhere. I call this keeping a small footprint in my application. By keeping the points where my application touches my more generic code as small as possible, it makes it easier for me to fix bugs, upgrade frameworks, add features, or alter functionality. +
  2. +
  3. + The second reason is that it's less code. By reusing the same method over and over again, I don't repeat myself and this is valuable in any programming environment. It also makes the code my visitors have to download smaller. +
  4. +
+

+ jQuery actually has a slightly more refined system for writing reusable "widgets" like these. Rather than encourage you to drop them into functions like the above example (which is really rather crude) it encourages you to write jQuery plug-ins. Here's what that would look like: + +

jQuery.fn.faq = function(options) {
+    var settings = jQuery.extend({
+        terms: 'dt',
+        definitions: 'dd'
+    }, options); 
+	//"this" is the current context; in this case, the elements we want to turn into faq layouts
+    $(this).find(settings.terms).hide().end().find(settings.definitions).click(function() {
+        $(this).next().slideToggle();
+    });
+    return this;
+};
+ +

+ which you would use thusly: +

+
$('#faq').faq();
+ +

+ But looking at the example above, there's not much difference between declaring our faq function this way vs. declaring it as a stand alone function. Granted, it's not in the global namespace, but we could have just as easily added it to a namespace of our own. By attaching it to jQuery we can chain it with other jquery methods. The other benefit is that the "this" inside our function is the current context of whatever is in the jQuery chain at that moment. By using this pattern for plug-ins we're able to make our plug-in look like it's part of jQuery, but other than that, our plug-in is basically a single function that takes the current jQuery context, does stuff to it, and then returns the context for the next item in the chain. There's not a lot of complexity here, which makes it easy for anyone to write jQuery plug-ins - they're just single functions. +

+ +

+ Note that it is possible to write more complex plugins with jQuery with methods and state. This kind of pattern is supported with the jQuery UI plugin system and doesn't use the same mechanism as the basic plugin (like our faq example). Instead, you attach an object with methods and properties to the jQuery object (i.e. $.ui.tabs). There's a shortcut to invoke this object ($(selector).tabs()) so that you can continue chaining as with the faq plugin. But because it doesn't return a reference to the tabs object created for the items in your selector, you're forced to call that selector again to invoke methods on it. Instead of calling myTabInstance.add(url, label, index) you must execute the selector again and call your function by name (as a string): $(selector).tabs('add', url, label, index);. This means you're running your selector twice (unless you store it in a variable somewhere), and that you don't ever have a pointer to the "add" method that you can do things like bind or delay. This post is focused on the MooTools and jQuery cores, and while jQuery's UI system does provide this functionality, it's not something that comes with jQuery by default. +

+ + +

Reusing Code with MooTools

+ +

+ In MooTools when you want to define a pattern, you're more likely to use either a Class or implement a method into a native object (into String, for example). +

+ +

+ Rather than give you an almost completely different language from JavaScript's native style, MooTools attempts to walk the middle ground between defining its own custom syntax and extending JavaScript's own design patterns. One of the ways it does this is by extending the prototypes of the native objects in the language and in the DOM. This means that if you needed a method to trim a string, MooTools encourages you to add that method to String itself (note that String.trim is already in MooTools; you don't need to add this yourself): +

+ +
String.implement({
+    trim: function() {
+        return this.replace(/^\s+|\s+$/g, '');
+    }
+});
+ +

+ This means you can just execute " no more spaces on the end! ".trim() and get back "no more spaces on the end!". Some would say that implementing properties into native prototypes is inappropriate. It's the reason why MooTools and Prototype.js can't play well with each other - any framework that manipulates prototypes of natives doesn't play well with any other framework that does the same. If I define String.prototype.foo() and another library on the same page defines it, too, which ever one comes last wins. In a way, this is similar to the problem we face with the global window namespace. This is how JavaScript works. This is how JavaScript 1.8 has added so many features. It adds them to the prototypes. +

+

+ The MooTools developers include a robust framework that is easy for you to extend with your own functionality with the intention that people who include the framework in the page are going to use it, not some other framework. It's actually kind of rude to ask users to download two frameworks. The only reason to include two frameworks is because you want to use plug-ins from both, and in the minds of the MooTools authors (myself included), if you want a plug-in that isn't available with the framework of your choice, it's more appropriate for you to spend the time porting it to your environment than to ask your users to download another framework. +

+

+ Once you learn how JavaScript works and see the power of extending native objects, a whole new level of programming opens up. You can write plug-ins that alter Elements or Dates or Functions. While some might argue that adding methods to natives this way is a kind of pollution, I'd argue that this is how JavaScript is meant to be used. It is a design feature of the language. By attaching methods to natives you allow your code to be concise and compartmentalized. jQuery does this too, but limits its prototype enhancements to the jQuery object. +

+ +

+ While you can easily chain multiple method calls on the jQuery object, on any other type of object you have to use + generics. For example, in jQuery if you want to trim a string and then iterate over each line, you would have to write: +

+ +
$.each( $.trim( $('span.something').html() ).split("\n"), function(i, line){alert(line);});
+ +

But because MooTools modifies prototypes, you can do this:

+ +
$('span.something').get('html').trim().split("\n").each(function(line){alert(line);});
+ +

+ Taking a look at this makes it extremely clear how powerful it is to + modify prototypes. Chaining on DOM elements isn't the only place chaining is + useful. MooTools lets you chain methods on any object, including + running a method on multiple elements at once. +

+ +

+ The key here is that at the heart of the MooTools framework is the notion that it's there to let you program what you want. If there's functionality that's not in the core, you can extend it and add your own. The job of the core is not to provide everyone with every bit of functionality that they could ever want, but to provide the tools that allow you write the things that you want. A big part of that is making it easier to extend the prototypes of natives, and take advantage of prototypal inheritance. You can do these things with vanilla JavaScript but MooTools makes it easier and more pleasant. + +

+ + + +

MooTools and Inheritance

+ +

+ Despite its name, the MooTools Class function is not really a class nor does it create them. It has design patterns that might remind you of classes in a more traditional programming language, but really Class is all about objects and prototypal inheritance. (Unfortunately, using words like "class" are the most convenient way to describe these things, so for the purposes of this article, when I refer to "classes" I'm referring to functions that return objects - which I'll call "instances" - that inherit from a prototype.) +

+

+ To make a class, you pass an object to the Class constructor like this: +

+ +
var Human = new Class({
+    initialize: function(name, age) {
+        this.name = name;
+        this.age = age;
+    },
+    isAlive: true,
+    energy: 1,
+    eat: function() {
+        this.energy = this.energy + 1; //same as this.energy++
+    }
+});
+ +

+ You pass Class an object (above, we pass an object with members like "isAlive" and "eat") and this object becomes the prototype of every instance of that class. To create an instance, you call it like this: +

+
var bob = new Human("bob", 20); //bob's name is "bob" and he's 20 years old.
+

+ Now we have an instance of Human. bob has the properties of the object we defined when we created our Human class. But the important thing is that bob has these properties through inheritance. When we reference bob.eat, bob doesn't really have this property. JavaScript looks at bob and he doesn't have an eat method, so it looks up the inheritance chain and finds it on the object we passed when we created the Human class. This is true for energy, too. At first glance this looks potentially bad; we don't want all the humans we create to gain energy every time that bob eats. The important thing to recognize is that the first time we assign a value to bob's energy, we assign him his own value and we no longer look at the prototype for it. So the first time bob eats, he gets his own definition for energy (set to 2). +

+
bob.eat(); //bob.energy == 2
+

+ Note that bob's name and age are unique to him; these are assigned to him when the class is initialized in the initialize method. +

+

+ This whole pattern may seem a little odd to you, but the value here is that we can define functionality for a pattern and create instances of that pattern every time we need it. Each instance maintains its own state. So if we create another instance each one is independent of the other, but inherits from the same base pattern: +

+ +
var Alice = new Human();
+//alice.energy == 1
+//bob.energy == 2
+ +

+ Where things get really interesting is when we want to augment this behavior. +

+ + +

Extending and Implementing Classes

+ +

+ Let's revisit our jQuery faq plug-in. What would happen if we wanted to add more functionality to that plug-in. What if we wanted to make an ajax version that fetched the answers to the questions from the server? Let's imagine that the faq plug-in was authored by someone else and we want to add more to it without altering it in any way (we don't want to fork it). +

+

+ Our only real choices are to either duplicate the faq plug-in's logic entirely (remember, it's a single function), essentially forking it, or we can invoke it and then add more logic to it. Given a choice, the latter seems to save us the most trouble. It would look something like this: +

+
jQuery.fn.ajaxFaq = function(options) {
+    var settings = jQuery.extend({ 
+		//some ajax specific options like the url to request terms from
+        url: '/getfaq.php'
+        definitions: 'dd'
+    }, options); 
+	//"this" is the current context; in this case, the elements we want to turn into faq layouts
+    $(this).find(settings.definitions).click(function() {
+        $(this).load(.....); //the logic to load the content from the term
+    });
+    this.faq(); //call our original faq plug-in
+});
+

+ This has some down sides. First of all, our faq class is going to repeat our selector for the definitions, which might be expensive; there's no way to store the retrieved definitions and pass it on for the second time they are needed. Secondly, we can't add our ajax logic into the middle of the faq plug-in's own logic for displaying the definition. The original plug-in called slideToggle which expands the definition using an effect. This is problematic because this effect is going to go off before our ajax finishes loading. There's no real solution here unless we just duplicate the entire faq plug-in. +

+

+ Now let's consider our MooTools Human class. It has properties like isAlive and energy and it has a method called eat. What if we wanted to make a new version of Human that had additional properties? With MooTools, we extend the class: +

+
var Ninja = new Class({
+    Extends: Human,
+    initialize: function(name, age, side) {
+        this.side = side;
+        this.parent(name, age);
+    },
+    energy: 100,
+    attack: function(target) {
+        this.energy = this.energy - 5;
+        target.isAlive = false;
+    }
+});
+

+ You can see that we've added a lot of functionality here into a subclass. This subclass has all these properties that are unique to Ninjas. Ninjas start off with an initial energy value of 100. Ninjas get a side. They also get an attack method that lets them kill other Humans, but it costs the Ninja energy. +

+ +
var bob = new Human('Bob', 25);
+var blackNinja = new Ninja('Nin Tendo', 'unknown', 'evil');
+//blackNinja.isAlive = true
+//blackNinja.name = 'Nin Tendo'
+blackNinja.attack(bob);
+//bob never had a chance
+ +

+ Picking this apart a bit, there are some interesting things to consider here. Note that we have an initialize method in the Ninja class. This would appear to overwrite the initialize method in the Human class, but we can still access it by calling this.parent, passing along the arguments that the parent class's initialize expects. Further, we can control when our logic occurs; before or after the call to the parent. We can assign new values to properties (like the energy value) and we can define new functionality. Imagine if we could do this with our faq plug-in for jQuery. We could load our ajax and THEN slide open the value. +

+

+ MooTools has another pattern called a Mixin. Unlike the parent to + child relationship that is defined by extending one class into a + subclass, you can also define classes that are mixed into other + classes to imbue them with their properties. Here's an example: +

+ +
var Warrior = new Class({
+    energy: 100,
+    kills: 0,
+    attack: function(target) {
+        target.isAlive = false;
+        this.energy = this.energy - 5;
+        this.kills++;
+    }
+});
+ +

+ Here we've broken the qualities that make a Ninja different from a Human and put them in a class of their own. This lets us reuse this code outside of Ninja. We could then imbue our Ninja class with the qualities of a warrior like so: +

+ +
var Ninja = new Class({
+    Extends: Human,
+    Implements: Warrior, //can be an array if you want to implement more than one
+    initialize: function(name, age, side) {
+        this.side = side;
+        this.parent(name, age);
+    }
+});
+ +

+ Ninja still works as it did before, but Warrior is at our disposal to reuse: +

+ +
var Samurai = new Class({
+  Extends: Human,
+  Implements: Warrior,
+  side: 'good'
+});
+ +

+ Now we have a Samurai class and a Ninja class. But look at how little code both Ninja and Samurai took to define. Both of them are similar in that they are humans with warrior qualities, but they are different in that samurais are always, always good, while ninjas have shifting allegiances. By spending the time to write a Human class and a Warrior class, we're able to have three different classes with no repetition of code while maintaining a very granular level of control over when methods are called and how they relate to each other. Each instance we create has its own state and the code itself is very legible. +

+ +

+ Now that you have an overview of how classes work in MooTools, let's look at our faq class that we wrote in jQuery and write it as we would in MooTools and then extend it to add Ajax to it just as we did with jQuery. +

+
+var FAQ = new Class({
+	//Options is another class provided by MooTools
+	Implements: Options,
+	//these are the default options
+	options: {
+		terms: 'dt',
+		definitions: 'dd'
+	},
+	initialize: function(container, options) {
+		//we store a reference to our container
+		this.container = $(container);
+		//setOptions is a method provided by the Options mixin
+		//it merges the options passed in with the defaults
+		this.setOptions(options);
+		//we store the terms and definitions
+		this.terms = this.container.getElements(this.options.terms);
+		this.definitions = this.container.getElements(this.options.definitions);
+		//we call our attach method
+		//by breaking this into its own method
+		//it makes our class easier to extend
+		this.attach();
+	},
+	attach: function(){
+		//loop through the terms
+		this.terms.each(function(term, index) {
+			//add a click event to each one
+			term.addEvent('click', function(){
+				//that calls our toggle method for
+				//the current index
+				this.toggle(index);
+			}, this);
+		}, this);
+	},
+	toggle: function(index){
+		//toggle open the definition for the given index
+		this.definitions[index].slide('toggle');
+	}
+});
+
+ +

+ Woah. That's a lot of code. Even if we remove all the comments it's still two dozen lines long. I already illustrated above that we could build this plug-in with roughly the same amount of code as the jQuery version. So why is this one so much longer? Well, we've made it much more flexible. To use the class, we just call the constructor, like this: +

+ +
var myFAQ = new FAQ(myContainer);
+//and now we can call methods on it if we want:
+myFAQ.toggle(2); //toggle the 3rd element
+
+ +

+ We can access methods and properties of the instance. But what about our ajax functionality? The problem with our ajax extension to the jQuery version was that we couldn't delay the opening of the definition until after it loaded. We don't have that problem with our MooTools version: + +

+ +
FAQ.Ajax = new Class({
+	//this class inherits the properties of FAQ
+	Extends: FAQ,
+	//it also gets a new option in addition to the other defaults
+	//this one for url, that we're going to append the index of the
+	//term to; in reality we might make this more robust, but for
+	//this example it serves the purpose
+	options: {
+		url: null;
+	},
+	//we're going to cache the results, so if a section is opened
+	//twice, we won't hit the server for the data
+	indexesLoaded: [],
+	toggle: function(index){
+		//if we've already loaded the definition
+		if (this.indexesLoaded[index]) {
+			//just call the previous version of toggle
+			this.parent(index);
+		} else {
+			//otherwise, request the data from the server
+			new Request.HTML({
+				update: this.definitions[index],
+				url: this.options.url + index,
+				//and when the data is loaded, expand the definition
+				onComplete: function(){
+					this.indexesLoaded[index] = true;
+					this.definitions[index].slide('toggle');
+				}.bind(this)
+			}).send();
+		}
+	}
+});
+
+ +

+ Now we have a version of our FAQ class that allows us to get the definitions from the server. Note that we were able to integrate the new logic in a way that doesn't expand the definition until after the content comes back from the server (which we couldn't do with the jQuery version). Also note that we really only had to describe the new functionality (the ajax) and little else. This extensibility makes it possible for you to create families of plug-ins that offer different shades of functionality. It also means that you can use someone else's plug-in and alter just the bits that you to be want different if you need to (without forking it). This helps explain why, for any given design pattern - a date picker, a tab interface, etc, that you typically only find a few plug-ins for MooTools. Most of the plug-ins you get either solve your problem or, if not, you can just extend them to add the things you need. + +

+ +

+ As I illustrated earlier, it's possible to write complex jQuery widgets with methods and state. Most of the code you write when doing this is vanilla JavaScript when you need to express logic that isn't related to the DOM. But jQuery's model doesn't offer a system for extending these instances into subclasses. Nor does it help you with mixins that can be reused easily. Finally, jQuery's plugins are always attached to DOM elements. If you wanted to write a class that, say, processed URLs, there's no stateful system for such a thing unless you write it yourself. +

+ + +

Decision Time

+ +

+ jQuery focuses on expressiveness, quick and easy coding, and the DOM while MooTools focuses on extension, inheritance, legibility, reuse, and maintainability. If you put those two things on opposite sides of a scale, the jQuery side translates into something with which it's easy to get started and see quick results but (in my experience) can turn into code that's harder to reuse and maintain (but really that's up to you; it's not jQuery's problem, per se), while the MooTools side takes longer to learn and requires you to write more code upfront before you see results, but afterwards is more reusable and more maintainable. +

+

+ Further, the MooTools core does not contain every feature you can imagine and neither does the jQuery core. Both frameworks keep their cores rather lean, leaving it to you and others to write plug-ins and extensions. Their job is not to give you every feature you could want but to give you the tools so that you can implement anything you can imagine. This is the power of JavaScript, and of JavaScript frameworks in general, and both frameworks excel at it. MooTools takes a more holistic approach and gives you tools to write anything you can imagine beyond the scope of the DOM, but pays the price by having a steeper learning curve. MooTools' extensible and holistic approach gives you a superset of jQuery's features, but jQuery's focus on a slick DOM API doesn't preclude you from using the native inheritance methods of JavaScript or from using a class system like MooTools if you want it. +

+

+ This is why I say that both frameworks are excellent choices. My effort here has been to highlight the differences in philosophies between the two codebases and highlight their advantages and disadvantages. I doubt I've been successful in keeping my preference for MooTools completely in check, but hopefully this has been helpful. Regardless of which framework you choose to work with, you now know a lot more about both, hopefully. If you have the luxury of time, I strongly recommend implementing a site with each. Then write your own review of them both and maybe your perspective will highlight some things I missed. +

+

A history of this document can be viewed on github.

+

+ +

+
+

+ About me: I am a MooTools contributor and I blog about JavaScript and other things on my site Clientcide as well as release numerous plug-ins for MooTools. I am the author of MooTools Essentials as well as the MooTools online tutorial. I work at a company in the SF Bay Area called Cloudera. I can be contacted thusly. +

+ + +
+

A note on comments here: These comments are moderated. No comments will show up until they are approved. Comments that are not productive (i.e. inflammatory, rude, etc) will not be approved. Similarly, "fan" comments won't be approved either - i.e. no "FrameworkX Rulez! It's better than FrameworkY for realz!" are not constructive comments. +

+
+ + +
+ + + + + + + \ No newline at end of file From 2c855e7a047f591dbe6ce34a664444a914fcd2cb Mon Sep 17 00:00:00 2001 From: Ivan Ivanov Date: Mon, 20 Aug 2012 01:05:35 +0400 Subject: [PATCH 2/8] A couple of chapters are translated --- index_ru.html | 250 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 150 insertions(+), 100 deletions(-) diff --git a/index_ru.html b/index_ru.html index f986717..5eb7f44 100644 --- a/index_ru.html +++ b/index_ru.html @@ -112,162 +112,212 @@

jQuery vs MooTools

- Most people getting started with JavaScript these days are faced with the challenging task of picking a library to use, or at least which one to learn first. If you're working for a company chances are they have already chosen a framework for you, in which case the point is somewhat moot. If this is the case and they've chosen MooTools and you're used to jQuery, then this article might still be of some use to you. -

-

- Every day on twitter I see numerous posts that boil down to "MooTools or jQuery?" This article aims to help you make that choice. -

-

Disclaimer

-

- I am a MooTools developer. I work on the MooTools framework. I blog about MooTools. I wrote the main online tutorial and the book about MooTools. Obviously, I have a perspective that is somewhat biased. I'll also point out that I don't use jQuery that often. If you're a jQuery developer and see anything that I have misrepresented here, please contact me and help me rectify the issue. My objective here is to be helpful and accurate to people - not to sell one framework over another. -

- -

Purpose

-

- Helping you make a choice between these two frameworks involves me telling you how they are different. I'll start out by saying that both of them are excellent choices. You can't make a wrong choice here. Both frameworks have their strengths and weaknesses, but, in general, they are both great choices. There are other frameworks out there that are worth digging into as well. Dojo, Prototype, YUI, Ext and others are all great choices. Which one you choose really has more to do with your own style and what you need to accomplish. The purpose of this article is to focus on MooTools and jQuery, as increasingly these are the two frameworks that I see a lot of people considering. Finally, I'm not trying to convince anyone to switch from one framework to the other. There are interesting things about both frameworks from which you can learn. You can read a little more about this article and why I wrote it in my blog post on Clientcide where I announced it. + В наши дни большинство людей, начинающих использовать JavaScript, сталкиваются с непростой задачей выбора библиотеки + для дальнейшего использования, или, по крайней мере, какую из них изучать в первую очередь. + Если вы работаете в какой-либо компании, то выбор, вероятно, уже сделан за вас, и тогда этот вопрос отпадает. Тем не менее, если + вы привыкли к jQuery, а компания заставляет использовать MooTools, + эта статья все-таки может оказаться вам полезной. +

+

+ Каждый день + в твиттере + я вижу множество постов, которые сводятся к "MooTools или jQuery?". Эта статья поможет вам определиться с выбором. +

+

Отказ от ответственности

+

+ Я — разработчик MooTools. Я работаю над этим фреймворком. Я веду блог про MooTools. Я написал + основное онлайн руководство и + книгу о MooTools. + Очевидно, моя точка зрения несколько предвзята. Подчеркну также, что я не особо часто использую jQuery. + Если вы разработчик jQuery и увидели, что я исказил что-нибудь, пожалуйста, свяжитесь со + мной, чтобы помочь исправить это недоразумение. Моя задача здесь — помочь людям сделать выбор, + а не выставлять один фреймворк перед другим в более выгодном свете. +

+ +

Цель данной статьи

+

+ Желание помочь вам выбрать между jQuery и MooTools заставляет меня рассказать вам, насколько + они отличаются друг от друга. Начну с того, что они оба являются прекрасными фреймворками. Сделать неправильный выбор здесь невозможно. + Разумеется, у каждого из них есть свои достоинства и недостатки, но, в целом, они оба — отличный выбор. + Есть также и другие фреймворки, которые стоят того, чтобы взглянуть на них более подробно. Dojo, + Prototype, YUI, + Ext и прочие — тоже прекрасный выбор. Какой именно из них подойдет, + больше зависит от вашего стиля и от того, что именно вы хотите сделать. Цель данной статьи — сфокусироваться + на MooTools и jQuery, так как именно из них двоих все больше и больше людей пытаются выбирать. В конце концов, + я не пытаюсь никого убедить переключиться с одного фреймворка на другой. В них обоих есть что почерпнуть + и чему научиться. Более подробно о том, что побудило меня написать эту статью, вы можете прочитать + в моем посте на Clientcide.

-

Table o' Contents

- +

Содержание

+ -

The Stats

+

Сухие цифры

- - + + - + - + - + - - - + + + - - - + + + - - - + + + - - - + + + - - + + - - - + + + - - - + + + - + - - - + + + - - - + + +
jQuery CoreMooTools CoreЯдро jQueryЯдро MooTools
Library SizeРазмер библиотеки 55.9K 64.3K
FeaturesОсобенности
LicenseЛицензия MIT & GPL MIT
DOM UtilitesyesyesФункции для работы с DOMестьесть
AnimationyesyesАнимацияестьесть
Event HandlingyesyesОбработка событиеестьесть
CSS3 Selectorsyes (a subset)yes (a subset)CSS3 селекторыесть (подмножество)есть (подмножество)
Ajaxyesyesестьесть
Native Extensions (excluding Element)about a dozen for Array, Object, and Stringabout six dozen for Array, Object, String, Function, and NumberНативные расширения (кроме Element)около 12 для Array, Object, и String70+ для Array, Object, String, Function, и Number
InheritanceNot supported directly with jQueryProvided with Class constructorНаследованиеНапрямую не поддерживается jQueryПредоставляется конструктором Class
Other ConsiderationsПрочие соображения
plug-insHundreds of unofficial plug-ins in a directory at plugins.jquery.comRoughly 4 dozen official plug-ins available at mootools.net/more. Unofficial plugin directory at mootools.net/plugins.ПлагиныСотни неофициальных плагинов — plugins.jquery.comОколо 50 официальных плагинов тут — mootools.net/more. Неофициальные плагины тут — mootools.net/plugins.
Official UI libraryyesnoОфициальная библиотека UIестьнет

- Information based on data from jquery.com, mootools.net, and wikipedia.com. + Информация основана на данных jquery.com, mootools.net, и wikipedia.com.

-

The Mottos Say It All

- - +

Девизы говорят сами за себя

- If you go to the jQuery site, here's what it says at the top of the page: + Если вы зайдете на сайт jQuery, вот что вы увидите вверху страницы:

-
jQuery is a fast and concise JavaScript Library that simplifies HTML document traversing, event handling, animating, and Ajax interactions for rapid web development. jQuery is designed to change the way that you write JavaScript.
+
+ jQuery — быстрая и компактная JavaScript библиотека, которая упрощает работу с HTML документами, + обработкой событий, анимацией и Ajax для быстрой веб-разработки. jQuery cоздан, чтобы изменить + то, как вы обычно пишете JavaScript. +

- ...and if you go to MooTools, this is what you'll find: + ...а вот что написано на официальном сайте MooTools:

-
MooTools is a compact, modular, Object-Oriented JavaScript framework designed for the intermediate to advanced JavaScript developer. It allows you to write powerful, flexible, and cross-browser code with its elegant, well documented, and coherent API.
+
MooTools — это компактный, модульный, объектно-ориентированный JavaScript фреймворк, созданный для + JavaScript разработчиков среднего и продвинутого уровня. Он позволяет писать мощный, гибкий и кроссбраузерный + код с элегантным, понятным, логичным и хорошо документированным API. +

- I think this really sums it up. If you ask me (and you're reading this, so I'll assume you just have), the question isn't about which framework is better or worse. It's which one of these things above do you want to do? These two frameworks just aren't trying to do the same things. They overlap in the functionality they provide, but they are not trying to do the same things. + Я думаю, это действительно все неплохо суммирует. Если вы спросите меня (а поскольку вы это читаете, + я полагаю, что вы уже спросили), вопрос не в том, какой фреймворк лучше или хуже. А в том, что из вышеперечисленных вещей + вы хотели бы делать? Эти два фреймворка просто разработаны с разной целью. Разумеется, есть + некоторая функциональность, которая присутствует в них обоих, но, тем не менее, они не пытаются делать одно и то же.

-

- jQuery's description of itself talks about HTML, events, animations, Ajax, and web development. MooTools talks about object oriented-ness and writing powerful and flexible code. jQuery aspires to "change the way you write JavaScript" while MooTools is designed for the intermediate to advanced JavaScript developer. + Описание jQuery говорит о HTML, событиях, анимациях, Ajax и веб-разработке. MooTools говорит об + объектно-ориентированности и написании мощного и гибкого кода. jQuery стремится "изменить то, как вы обычно пишете JavaScript", + в то время как MooTools разработан для разработчиков среднего и продвинутого уровня.

-

- Part of this consideration is the notion of a framework vs a toolkit. MooTools is a framework that attempts to implement JavaScript as it should be (according to MooTools' authors). The aim is to implement an API that feels like JavaScript and enhances everything; not just the DOM. jQuery is a toolkit that gives you an easy to use collection of methods in a self-contained system designed to make the DOM itself more pleasant. It just so happens that the DOM is where most people focus their effort when writing JavaScript, so in many cases, jQuery is all you need. + Важно различать концепции фреймворка и набора инструментов (toolkit). MooTools — это фреймворк, который + пытается сделать JavaScript таким, каким он должен быть (согласно авторам MooTools). + Его цель — реализовать API, который выглядел бы как JavaScript, но расширял бы все, не только DOM. + jQuery — это toolkit, который дает вам удобный набор методов, которые делают работу с DOM более приятной. + Просто так получилось, что DOM — это то, на чем концентрируется большинство людей, которые пишут JavaScript, + так что, в большинстве случаев jQuery — все, что вам нужно.

- Most of the code you write when you write MooTools still feels like JavaScript. If you aren't interested in JavaScript as a language, then learning MooTools is going to feel like a chore. If you are interested in JavaScript and what makes it interesting, powerful, and expressive, then, personally, I think MooTools is the better choice. + Большая часть кода, которую вы пишете, используя MooTools, все еще выглядит как JavaScript. + Если вам не интересен JavaScript как язык, то изучение MooTools, скорей всего, станет для вас неприятной рутиной. + А если вам интересен JavaScript сам по себе, и то, что делает его таким мощным и выразительным, то + лично я думаю, что MooTools подойдет вам больше.

- - + -

The Learning Curve and The Community

- -

- First, jQuery is, by and large, easier to learn. It has an almost colloquial style that almost doesn't feel like programming. If all you want is to get something working quickly without learning JavaScript, jQuery is probably a better choice for you. It's not that MooTools can't help you accomplish the same things, but I'll admit that MooTools can be a little harder to get the hang of if you're new to JavaScript and also that there are just a lot of resources out there to help you learn jQuery - more than there are for MooTools at least. -

- -

- If you compare the jQuery community (see the "Discussion" page on jQuery) and the MooTools community (irc, mailing list, and unofficial forum) you'll quickly discover two things: 1) the jQuery community is far larger (I attribute this mostly to the point I made above about how easy it is to learn, but also because...) and 2) they are more active in promoting the library. If you measure jQuery and MooTools on metrics like the number of people using it, the number of search queries run on Google, the number of books sold, etc, you'll see jQuery is ahead by a wide margin. -

- -

- To tell you why you might consider MooTools I'll first need to talk a little bit about what both the frameworks do. Ultimately which framework you choose is going to come down to what you want to accomplish and how you like to program (and maybe even if you like to program, at least in JavaScript). +

Сложность изучения и сообщество

+

+ Во-первых, jQuery, по большому счету, легче в освоении. Стиль его кода близок к разговорному и даже почти не + ощущается как программирование. Если вам нужно склепать что-нибудь по-быстрому, не изучая JavaScript, то + jQuery, вероятно, лучший выбор для вас. Это не значит, что MooTools не сможет вам помочь в таких вещах, но + я признаю, что MooTools может оказаться слегка сложнее в изучении, если вы новичок в JavaScript, а также + что ресурсов, готовых помочь в изучении jQuery, ощутимо больше, чем аналогичных для MooTools. +

+

+ Если вы сравните сообщество jQuery (смотрите страницу "Обсуждение" на сайте jQuery) + и сообщество MooTools (irc, + mailing list, и + unofficial forum), + вы быстро обнаружите две вещи: + 1) сообщество jQuery гораздо больше (я приписываю это большей частью тому, насколько легче его изучать, однако есть еще одна причина...), + 2) оно более активно продвигает свою библиотеку. + Если вы измерите jQuery и MooTools с той точки зрения, сколько + человек их использует, сколько запросов о них делается в Гугле, сколько было продано книг и так далее, + вы увидите, что jQuery находится впереди с большим отрывом. +

+

+ Чтобы рассказать о том, почему вам, возможно, стоит поглядеть в сторону MooTools, я сперва должен поговорить о том, + что вообще оба эти фреймворка делают. В конечном счете, какой фреймворк вы выберете, зависит от того, что вы хотели бы + получить, и как вам нравится программировать (а может быть, и нравится ли вам программировать вообще, + по крайней мере на JavaScript).

From 607e72d13b84f79403edbe9027175f9c2b2e9164 Mon Sep 17 00:00:00 2001 From: Ivan Ivanov Date: Mon, 20 Aug 2012 10:19:46 +0400 Subject: [PATCH 3/8] Another couple of chapters --- index_ru.html | 74 ++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 56 insertions(+), 18 deletions(-) diff --git a/index_ru.html b/index_ru.html index 5eb7f44..de62b0e 100644 --- a/index_ru.html +++ b/index_ru.html @@ -153,7 +153,7 @@

Содержание

  • Девизы говорят сами за себя
  • Сложность изучения и сообщество
  • -
  • Для чего подходит JavaScript
  • +
  • Для чего годится JavaScript
    • Больше, чем просто DOM
    • Наследование в JavaScript
    • @@ -321,26 +321,64 @@

      Сложность изучения и сообщество

      -

      What JavaScript Is Good For

      - -

      - Part of making this choice is asking what you want to do with JavaScript. Let's consider vanilla JavaScript. No framework; just plain old JS. JavaScript gives you native objects like Strings, Numbers, Functions, Arrays, Dates, Regular Expressions, and more. JavaScript also gives you an inheritance model - a somewhat esoteric model called prototypal inheritance (which I'll talk about more later). These building blocks and the concept of inheritance are the bread and butter of any programming language and they have absolutely nothing to do with browsers or the web or CSS or HTML. You could write anything you wanted to in JavaScript. Tic-tac-toe, chess, photoediting, a web server, whatever. It just so happens that 99% of all the JavaScript out there is run in browsers and that's what we think of it as. The programming language for browsers. -

      -

      - Understanding that the browser, the DOM, is just where we happen to use JS most of the time but that it's actually a very robust and expressive programming language will help you understand the difference between MooTools and jQuery. +

      Для чего годится JavaScript

      +

      + Важно понять, что именно вы хотите делать с помощью JavaScript. Давайте рассмотрим "чистый" JavaScript. Без фреймворков, просто старый добрый JS. + JavaScript предоставляет изначально нативные объекты вроде + Strings, + Numbers, + Functions, + Arrays, + Dates, + Regular Expressions, + и так далее. + JavaScript также предоставляет вам способ наследования — довольно эзотерический способ, + называемый прототипное наследование + (о котором мы поговорим позже). Вот эти строительные блоки и концепция наследования — хлеб с маслом + любого языка программирования, и они не имеют совершенно никакого отношения к браузерам, вебу или CSS с HTML. + Вы можете написать на JavaScript все, что хотите. Крестики-нолики, шахматы, обработчик фотографий, + веб-сервер, что угодно. Просто так получилось, что 99% всего JavaScript запускается в браузерах, и поэтому + мы так о нем думаем. Как о языке программирования для браузеров. +

      +

      + Понимание того, что браузеры и DOM — всего лишь то, для чего мы исторически больше всего используем + JavaScript, а на самом деле это очень надежный и выразительный язык программирования, поможет вам + понять различия между MooTools и jQuery.

      -

      More Than Just The DOM

      - -

      - If you think of the tasks that we want to accomplish in JavaScript strictly in terms of "get stuff on the page and do stuff to it" then jQuery is probably the best choice. It excels at offering a very expressive system for describing behavior on the page in a way that doesn't feel like programming sometimes. You can still use the rest of JavaScript to do what you want to do, but if you're focused on the DOM - changing CSS properties, animating things, fetching content via AJAX, etc - most of what you'll end up writing will be covered by jQuery, and what isn't will likely be plain-old JavaScript. jQuery does provide some methods that aren't about the DOM; for example, it provides a mechanism for iterating over arrays - $.each(array, fn) - or, for example, it offers a trim method for strings - $.trim(str). But there aren't a ton of these types of utility methods, which is fine because, for the most part, if you're just getting stuff out of the DOM, iterating over them, and altering them in some way (adding html, changing styles, adding event listeners for click and mouseover, etc) you don't need much else. -

      -

      - But if you think of JavaScript's scope in its full breadth, you can see that jQuery doesn't focus on things outside of the DOM. This is one of the reasons it is so easy to learn, but it also limits the ways it can help you write JavaScript. It's just not trying to be anything other than a solid programming system for the DOM. It doesn't address inheritance nor does it address the basic utilities of all the native types in the JavaScript language, but it doesn't need to. If you want to mess around with strings, dates, regular expressions, arrays and functions, you can. It's just not jQuery's job to help you do it. JavaScript as a language is there at your feet. jQuery makes the DOM your playground, but the rest of JavaScript is just not in its scope. -

      -

      - This is where MooTools is vastly different. Rather than focusing exclusively on the DOM (though, as I'll get into in a bit, it offers all the functionality that jQuery does but accomplishes this in a very different manner), MooTools takes into its scope the entire language. If jQuery makes the DOM your playground, MooTools aims to make JavaScript your playground, and this is one of the reasons why it's harder to learn. +

      Больше, чем просто DOM

      +

      + Если все ваши задачи, которые вы хотите решить с помощью JavaScript — это "взять эту штуку + со страницы и сделать с ней вот эти вот штуки", то jQuery, вероятно, для вас лучший выбор. + Ему прекрасно удается предоставлять очень выразительный способ описания поведения объектов на странице, + который иногда даже не похож на программирование. Вы по-прежнему можете использовать остальную часть + JavaScript для других целей, но если вы в основном сконцентрированы на DOM — изменении CSS свойств, + анимации объектов, получении данных через AJAX и тому подобном — большая часть того, что вы пишете, + будет покрыта jQuery, и эта часть не будет выглядеть как старый добрый JavaScript. + jQuery предоставляет несколько методов, не относящихся к DOM. Например, механизм для итерации + по массивам — $.each(array, fn) — + или, например, функцию для обрезания строк — $.trim(str). + Но этих методов там совсем немного, что и хорошо, поскольку в большей части кода вы просто + получаете всякие штуки из DOM, итерируете по ним и меняете каким-либо образом (добавляете html, + изменяете стили, добавляете обработчики события для click и mouseover и т.п.), и вам особо + ничего больше не нужно. +

      +

      + Но если вы подумаете о JavaScript в более широком смысле, вы увидете, что jQuery не фокусируется на + вещах помимо DOM. Это, кстати, одна из причин, почему его так легко изучать, но это также ограничивает + вас в предоставляемых библиотекой возможностях. Он даже просто не пытается быть чем-то большим, + чем отличной системой программирования для DOM. Он не обращает внимания ни на наследование, + ни на все нативные типы в языке JavaScript, но ему этого и не нужно. Если вам нужно возится со + строками, датами, регулярными выражениями, массивами и функциями, без проблем. Просто это уже + не работа jQuery. К вашим услугам обычный JavaScript. jQuery делает вам конфетку из DOM, но все остальное + уже выходит за его рамки. +

      +

      + Вот в чем отличие MooTools. Вместо того чтобы фокусироваться только на DOM (хотя, как вам дальше будет + видно, он предлагает всю ту же функциональность, что и jQuery, просто в совершенно другой манере), + MooTools включает в свои рамки весь язык. Если jQuery делает вам конфетку из DOM, MooTools пытается + сделать конфетку из самого JavaScript, и это одна из причин, по которой его сложнее изучать.

      From 254c0f29d7589a8c86a2c0c188bc4f3f98e87772 Mon Sep 17 00:00:00 2001 From: Ivan Ivanov Date: Mon, 20 Aug 2012 13:39:24 +0400 Subject: [PATCH 4/8] Another couple --- index_ru.html | 1343 +++++++++++++++++++++++++------------------------ 1 file changed, 696 insertions(+), 647 deletions(-) diff --git a/index_ru.html b/index_ru.html index de62b0e..43dd2d3 100644 --- a/index_ru.html +++ b/index_ru.html @@ -1,87 +1,87 @@ - - - jQuery vs MooTools: Choosing Between Two Great JavaScript Frameworks - - - - - - - - - - - - - + + + + - - -
      - -

      jQuery vs MooTools

      - -

      + + + +

      + +

      jQuery vs MooTools

      + +

      В наши дни большинство людей, начинающих использовать JavaScript, сталкиваются с непростой задачей выбора библиотеки для дальнейшего использования, или, по крайней мере, какую из них изучать в первую очередь. Если вы работаете в какой-либо компании, то выбор, вероятно, уже сделан за вас, и тогда этот вопрос отпадает. Тем не менее, если вы привыкли к jQuery, а компания заставляет использовать MooTools, эта статья все-таки может оказаться вам полезной. -

      -

      - Каждый день +

      +

      + Каждый день в твиттере я вижу множество постов, которые сводятся к "MooTools или jQuery?". Эта статья поможет вам определиться с выбором. -

      -

      Отказ от ответственности

      -

      +

      +

      Отказ от ответственности

      +

      Я — разработчик MooTools. Я работаю над этим фреймворком. Я веду блог про MooTools. Я написал основное онлайн руководство и книгу о MooTools. @@ -132,10 +132,10 @@

      Отказ от ответственности

      Если вы разработчик jQuery и увидели, что я исказил что-нибудь, пожалуйста, свяжитесь со мной, чтобы помочь исправить это недоразумение. Моя задача здесь — помочь людям сделать выбор, а не выставлять один фреймворк перед другим в более выгодном свете. -

      +

      -

      Цель данной статьи

      -

      +

      Цель данной статьи

      +

      Желание помочь вам выбрать между jQuery и MooTools заставляет меня рассказать вам, насколько они отличаются друг от друга. Начну с того, что они оба являются прекрасными фреймворками. Сделать неправильный выбор здесь невозможно. Разумеется, у каждого из них есть свои достоинства и недостатки, но, в целом, они оба — отличный выбор. @@ -147,9 +147,9 @@

      Цель данной статьи

      я не пытаюсь никого убедить переключиться с одного фреймворка на другой. В них обоих есть что почерпнуть и чему научиться. Более подробно о том, что побудило меня написать эту статью, вы можете прочитать в моем посте на Clientcide. -

      - -

      Содержание

      +

      + +

      Содержание

      - -

      Сухие цифры

      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      Ядро jQueryЯдро MooTools
      Размер библиотеки55.9K64.3K
      Особенности
      ЛицензияMIT & GPLMIT
      Функции для работы с DOMестьесть
      Анимацияестьесть
      Обработка событиеестьесть
      CSS3 селекторыесть (подмножество)есть (подмножество)
      Ajaxестьесть
      Нативные расширения (кроме Element)около 12 для Array, Object, и String70+ для Array, Object, String, Function, и Number
      НаследованиеНапрямую не поддерживается jQueryПредоставляется конструктором Class
      Прочие соображения
      ПлагиныСотни неофициальных плагинов — plugins.jquery.comОколо 50 официальных плагинов тут — mootools.net/more. Неофициальные плагины тут — mootools.net/plugins.
      Официальная библиотека UIестьнет
      -

      - Информация основана на данных jquery.com, mootools.net, и wikipedia.com. -

      - - -

      Девизы говорят сами за себя

      -

      + +

      Сухие цифры

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      Ядро jQueryЯдро MooTools
      Размер библиотеки55.9K64.3K
      Особенности
      ЛицензияMIT & GPLMIT
      Функции для работы с DOMестьесть
      Анимацияестьесть
      Обработка событиеестьесть
      CSS3 селекторыесть (подмножество)есть (подмножество)
      Ajaxестьесть
      Нативные расширения (кроме Element)около 12 для Array, Object, и String70+ для Array, Object, String, Function, и Number
      НаследованиеНапрямую не поддерживается jQueryПредоставляется конструктором Class
      Прочие соображения
      ПлагиныСотни неофициальных плагинов — plugins.jquery.comОколо 50 официальных плагинов тут — mootools.net/more. Неофициальные плагины тут — mootools.net/plugins.
      Официальная библиотека UIестьнет
      +

      + Информация основана на данных jquery.com, mootools.net, и wikipedia.com. +

      + + +

      Девизы говорят сами за себя

      +

      Если вы зайдете на сайт jQuery, вот что вы увидите вверху страницы: -

      -
      +

      +
      jQuery — быстрая и компактная JavaScript библиотека, которая упрощает работу с HTML документами, обработкой событий, анимацией и Ajax для быстрой веб-разработки. jQuery cоздан, чтобы изменить то, как вы обычно пишете JavaScript.
      -

      - ...а вот что написано на официальном сайте MooTools: -

      -
      MooTools — это компактный, модульный, объектно-ориентированный JavaScript фреймворк, созданный для +

      + ...а вот что написано на официальном сайте MooTools: +

      +
      MooTools — это компактный, модульный, объектно-ориентированный JavaScript фреймворк, созданный для JavaScript разработчиков среднего и продвинутого уровня. Он позволяет писать мощный, гибкий и кроссбраузерный код с элегантным, понятным, логичным и хорошо документированным API.
      -

      +

      Я думаю, это действительно все неплохо суммирует. Если вы спросите меня (а поскольку вы это читаете, я полагаю, что вы уже спросили), вопрос не в том, какой фреймворк лучше или хуже. А в том, что из вышеперечисленных вещей вы хотели бы делать? Эти два фреймворка просто разработаны с разной целью. Разумеется, есть некоторая функциональность, которая присутствует в них обоих, но, тем не менее, они не пытаются делать одно и то же. -

      -

      +

      +

      Описание jQuery говорит о HTML, событиях, анимациях, Ajax и веб-разработке. MooTools говорит об объектно-ориентированности и написании мощного и гибкого кода. jQuery стремится "изменить то, как вы обычно пишете JavaScript", в то время как MooTools разработан для разработчиков среднего и продвинутого уровня. -

      -

      +

      +

      Важно различать концепции фреймворка и набора инструментов (toolkit). MooTools — это фреймворк, который пытается сделать JavaScript таким, каким он должен быть (согласно авторам MooTools). Его цель — реализовать API, который выглядел бы как JavaScript, но расширял бы все, не только DOM. jQuery — это toolkit, который дает вам удобный набор методов, которые делают работу с DOM более приятной. Просто так получилось, что DOM — это то, на чем концентрируется большинство людей, которые пишут JavaScript, так что, в большинстве случаев jQuery — все, что вам нужно. -

      -

      +

      +

      Большая часть кода, которую вы пишете, используя MooTools, все еще выглядит как JavaScript. Если вам не интересен JavaScript как язык, то изучение MooTools, скорей всего, станет для вас неприятной рутиной. А если вам интересен JavaScript сам по себе, и то, что делает его таким мощным и выразительным, то лично я думаю, что MooTools подойдет вам больше. -

      +

      - -

      Сложность изучения и сообщество

      -

      + +

      Сложность изучения и сообщество

      +

      Во-первых, jQuery, по большому счету, легче в освоении. Стиль его кода близок к разговорному и даже почти не ощущается как программирование. Если вам нужно склепать что-нибудь по-быстрому, не изучая JavaScript, то jQuery, вероятно, лучший выбор для вас. Это не значит, что MooTools не сможет вам помочь в таких вещах, но я признаю, что MooTools может оказаться слегка сложнее в изучении, если вы новичок в JavaScript, а также что ресурсов, готовых помочь в изучении jQuery, ощутимо больше, чем аналогичных для MooTools. -

      -

      +

      +

      Если вы сравните сообщество jQuery (смотрите страницу "Обсуждение" на сайте jQuery) и сообщество MooTools (irc, mailing list, и @@ -312,17 +312,17 @@

      Сложность изучения и сообщество

      Если вы измерите jQuery и MooTools с той точки зрения, сколько человек их использует, сколько запросов о них делается в Гугле, сколько было продано книг и так далее, вы увидите, что jQuery находится впереди с большим отрывом. -

      -

      +

      +

      Чтобы рассказать о том, почему вам, возможно, стоит поглядеть в сторону MooTools, я сперва должен поговорить о том, что вообще оба эти фреймворка делают. В конечном счете, какой фреймворк вы выберете, зависит от того, что вы хотели бы получить, и как вам нравится программировать (а может быть, и нравится ли вам программировать вообще, по крайней мере на JavaScript). -

      - - -

      Для чего годится JavaScript

      -

      +

      + + +

      Для чего годится JavaScript

      +

      Важно понять, что именно вы хотите делать с помощью JavaScript. Давайте рассмотрим "чистый" JavaScript. Без фреймворков, просто старый добрый JS. JavaScript предоставляет изначально нативные объекты вроде Strings, @@ -330,27 +330,27 @@

      Для чего годится JavaScript

      Functions, Arrays, Dates, - Regular Expressions, + Regular Expressions и так далее. JavaScript также предоставляет вам способ наследования — довольно эзотерический способ, - называемый прототипное наследование + называемый прототипным наследованием (о котором мы поговорим позже). Вот эти строительные блоки и концепция наследования — хлеб с маслом любого языка программирования, и они не имеют совершенно никакого отношения к браузерам, вебу или CSS с HTML. Вы можете написать на JavaScript все, что хотите. Крестики-нолики, шахматы, обработчик фотографий, веб-сервер, что угодно. Просто так получилось, что 99% всего JavaScript запускается в браузерах, и поэтому - мы так о нем думаем. Как о языке программирования для браузеров. -

      -

      + мы так о нем думаем, как о языке программирования для браузеров. +

      +

      Понимание того, что браузеры и DOM — всего лишь то, для чего мы исторически больше всего используем JavaScript, а на самом деле это очень надежный и выразительный язык программирования, поможет вам понять различия между MooTools и jQuery. -

      - - -

      Больше, чем просто DOM

      -

      +

      + + +

      Больше, чем просто DOM

      +

      Если все ваши задачи, которые вы хотите решить с помощью JavaScript — это "взять эту штуку - со страницы и сделать с ней вот эти вот штуки", то jQuery, вероятно, для вас лучший выбор. + со страницы и сделать с ней вот эти штуки", то jQuery, вероятно, для вас лучший выбор. Ему прекрасно удается предоставлять очень выразительный способ описания поведения объектов на странице, который иногда даже не похож на программирование. Вы по-прежнему можете использовать остальную часть JavaScript для других целей, но если вы в основном сконцентрированы на DOM — изменении CSS свойств, @@ -363,8 +363,8 @@

      Больше, чем просто DOM

      получаете всякие штуки из DOM, итерируете по ним и меняете каким-либо образом (добавляете html, изменяете стили, добавляете обработчики события для click и mouseover и т.п.), и вам особо ничего больше не нужно. -

      -

      +

      +

      Но если вы подумаете о JavaScript в более широком смысле, вы увидете, что jQuery не фокусируется на вещах помимо DOM. Это, кстати, одна из причин, почему его так легко изучать, но это также ограничивает вас в предоставляемых библиотекой возможностях. Он даже просто не пытается быть чем-то большим, @@ -373,87 +373,136 @@

      Больше, чем просто DOM

      строками, датами, регулярными выражениями, массивами и функциями, без проблем. Просто это уже не работа jQuery. К вашим услугам обычный JavaScript. jQuery делает вам конфетку из DOM, но все остальное уже выходит за его рамки. -

      -

      +

      +

      Вот в чем отличие MooTools. Вместо того чтобы фокусироваться только на DOM (хотя, как вам дальше будет видно, он предлагает всю ту же функциональность, что и jQuery, просто в совершенно другой манере), MooTools включает в свои рамки весь язык. Если jQuery делает вам конфетку из DOM, MooTools пытается сделать конфетку из самого JavaScript, и это одна из причин, по которой его сложнее изучать. -

      - - -

      Inheritance with JavaScript

      - -

      - The JavaScript programming language has some really awesome things about it. For starters, it's a functional language, which means that it treats functions as high-order objects that can be passed around as variables just like any other object - strings or numbers for example. It's designed with this concept in mind and many of the methods and patterns in it work best when you write code this way. It's the difference between: -

      -
      for (var i = 0; i < myArray.length; i++) { /* do stuff */ }
      -

      - and -

      -
      myArray.forEach(function(item, index) { /* do stuff */ });
      -

      - JavaScript has an inheritance model that is not quite unique but at least rather rare in programming languages. Instead of classes that are defined that can be subclassed it passes along traits through prototypal inheritance. This means that objects inherit directly from other objects. If you reference a property on an object that inherits from another object, the language inspects the child object for that property and, if it doesn't find it, looks for it on the parent. This is how a method on, say, an array works. When you type: -

      -
      [1,2,3].forEach(function(item) { alert(item) }); //this alerts 1 then 2 then 3
      -

      - the method "forEach" is not a property of the array you declare ([1,2,3]), it is a property of the prototype for all Arrays. When you reference this method the language looks for a method called forEach on your array, and, not finding it, then looks at the prototype for all arrays. This means that the forEach method is not in memory once for every array in memory; it is only in memory for the prototype of arrays. This is incredibly efficient and ultimately quite powerful. (Side note: MooTools aliases the forEach method as each) -

      - - -

      Self Reference

      -

      - Javascript has a special word: "this". It's hard for me to succinctly define what "this" is all about but, by default, "this" is the object to which the current method belongs. It allows objects to refer to themselves within their methods as they would otherwise have no means to do so. This becomes important when you create children objects and have numerous instances of that object; how else could the method of an object refer to itself? When the actual copy of the method exists on the parent, not the child, the "this" keyword allows these instances to refer to their own state. (here's a much more complete description of the "this" keyword, and another from Mozilla.) -

      -

      - The "this" keyword allows objects that inherit from other objects to refer to themselves, but there are times when you may want to reference something else through "this". This is called binding, wherein you specify a different "this" for a method. The "each" method on Array allows you to specify the bound object with a second argument. Here's an example of where you might want to pass in a different "this": -

      +

      + + +

      Наследование в JavaScript

      +

      + Язык программирования JavaScript имеет несколько замечательных особенностей. Во-первых, это + функциональный язык, что означает, + что функции в нем являются объектами высшего порядка, которые могут передаваться повсюду в качестве + переменных, как и любые другие объекты, например, строки и числа. Его создавали, держа в уме эту + концепцию, и большинство его методов и подходов работают лучше всего, если вы пишете код в этом стиле. + Есть некоторые различия между: +

      +
      for (var i = 0; i < myArray.length; i++) { /* делать всякие штуки */ }
      +

      + и +

      +
      myArray.forEach(function(item, index) { /* делать всякие штуки */ });
      +

      + В JavaScript особенная модель наследования, + которая не то что бы уникальна, но, по крайней мере, довольно редко встречается в языках программирования. + Вместо классов, которые нужно объявлять отдельно, чтобы из них создавать подклассы, здесь используется + прототипное наследование. + Это означает, что объекты наследуются напрямую от других объектов. Если вы обращаетесь к свойству + какого-нибудь объекта, который наследуется от другого объекта, язык проверяет наличие данного свойства + у наследника, и если не находит, ищет такое свойство у родителя. Вот как этот метод работает, скажем, + на массивах. Когда вы печатаете: +

      +
      [1,2,3].forEach(function(item) { alert(item) }); // выводит сначала 1, потом 2, потом 3
      +

      + метод "forEach" + не является свойством массива, который вы объявили ([1,2,3]), это общее свойство прототипа + для всех массивов. Когда вы обращаетесь к этому методу, JavaScript ищет метод forEach в вашем массиве + и, не найдя, ищет его в прототипе всех массивов. Это означает, что метод forEach не хранится в памяти + для каждого отдельно взятого массива, а хранится в одном месте только для прототипа массивов. Это невероятно + эффективно и довольно мощно. (Замечание: в MooTools метод forEach доступен как each). +

      + + +

      Ссылки на самого себя

      +

      + В JavaScript есть ключевое слово "this". Сложно кратко сказать, что это вообще такое, но, по умолчанию, + "this" — это тот объект, которому принадлежит текущий метод. Это позволяет объектам ссылаться + на самих себя, а иначе они бы не имели такой возможности. Это становится важным, когда вы создаете + много дочерних объектов. Как иначе эти объекты могли бы сослаться на самих себя в своих же методах? + Когда настоящий метод расположен не в дочернем объекте, а в родителе, "this" позволяет + дочернему объекту обращаться к своему состоянию, а не к состоянию родителя. + (Здесь гораздо более подробно рассказано про "this", + и вот еще от Мозиллы.) +

      +

      + Ключевое слово "this" позволяет объектам, наследующимся от других объектов, обращаться к самим себе, + но бывают случаи, когда нужно обращаться через "this" к чему-нибудь другому. Это называется + binding (привязывание), + когда вы определяете другой "this" для метода. Метод "each" для массивов позволяет вам + передать вторым параметром связанный объект. Вот пример того, где вам может понадобиться передавать другой + "this": +

      var ninja = {
      -    weapons: ['katana', 'throwing stars', 'exploding palm technique'],
      +    weapons: ['катана', 'метательные звездочки', 'супер техника ударов ладонями, взрывающая сердца'],
           log: function(message) {
               console.log(message);
           },
           logInventory: function() {
               this.weapons.each(function(weapon) {
      -			//we want "this" to point to ninja...
      -            this.log('this ninja can kill with its ' + weapon);
      -        }, this); //so we pass "this" (which is ninja) to Array.each  
      +            // мы хотим, чтобы "this" ссылался на ниндзю
      +            this.log('У этого ниндзи есть ' + weapon);
      +        }, this); // так что мы передаем "this" (который ниндзя) в Array.each
           }
       };
       ninja.logInventory(); 
      -//this ninja can kill with its katana
      -//this ninja can kill with its throwing stars
      -//this ninja can kill with its exploding palm technique
      - -

      - In the example above, we bind ninja (which is "this" inside the logInventory method) to the method we pass to the array so that we can refer to the log property of ninja. If we didn't do this, "this" would be window. -

      -

      - These are just some examples of the power and expressiveness that JavaScript has to offer - inheritance, self reference and binding, and efficient prototype properties. The bad news is that vanilla JavaScript doesn't make these powerful things very useful or accessible, and this is where MooTools starts. It makes these types of patterns easy and rather pleasant to use. You end up writing more abstract code, and in the long run, this is a good thing - a powerful thing. Learning how these patterns are valuable and how to use them properly takes effort, but the up side is that the code you author is both highly reusable and much easier to maintain. I'll talk about these two things a bit more in a minute. -

      - - -

      MooTools Makes JavaScript Itself More Fun

      - -

      - Because MooTools focuses on making the JavaScript API itself more stable and coherent, it is focused less on giving you an interface that "changes the way you write JavaScript" and more on making JavaScript as a whole less frustrating; MooTools is an extension to the JavaScript language. MooTools tries to make JavaScript the way it is meant to be. A significant portion of the core library is spent on augmenting Function, String, Array, Number, Element and other prototypes. The other big thing it offers is a function called Class. -

      -

      - Now, Class looks to many people like it's trying to recreate a more classical inheritance model that one might find in Java or C++, but that's not the case. What Class does is make the prototypal inheritance model of JavaScript easier for you and me to access and take advantage of. I'll note that these concepts are not unique to MooTools (other frameworks offer similar functionality), but both of these concepts are not present in jQuery. jQuery does not offer an inheritance system nor does it offer any enhancements to native objects (Function, String, etc). This is not a deficiency of jQuery as the authors of jQuery could easily offer these things. Rather, they have designed a toolkit with a different goal in mind. Where MooTools aims to make JavaScript more fun, jQuery aims to make the DOM more fun and its designers have chosen to limit their scope to that task. -

      - - -

      jQuery Makes the DOM More Fun

      - -

      - And this is why jQuery is more accessible. It doesn't ask that you learn JavaScript inside and out. It doesn't throw you into the deep end with prototypal inheritance, binding, "this", and native prototypes. When you get started with jQuery in its official tutorial, this is the first jQuery code example you find: -

      - +// У этого ниндзи есть катана +// У этого ниндзи есть метательные звездочки +// У этого ниндзи есть супер техника ударов ладонями, взрывающая сердца + +

      + В примере выше мы привязываем ниндзю (который "this" внутри метода logInventory) к методу, + который мы передаем массиву, так что мы можем обращаться к свойству log у ниндзи. Если бы мы этого + не сделали, "this" был бы объектом window. +

      +

      + Это только пара примеров силы и выразительности языка JavaScript — наследования, ссылок на самих себя + и связывания, а также эффективного использования свойств в прототипах. Плохие новости в том, что + чистый JavaScript не предоставляет удобных возможностей работать со всеми этими вещами, и тогда на + сцену выходит MooTools. Он превращает эти подходы в простые и приятные в использовании. В итоге + вы пишете более абстрактный код, и, по большому счету, это хорошо. Научиться использовать эти подходы + правильно требует усилий, но, в конечном счете, ваш код с большей вероятностью можно будет повторно + использовать и гораздо легче поддерживать. Поговорим об этих двух вещах более подробно. +

      + + +

      MooTools делает Javascript более крутым

      +

      + Поскольку MooTools стремится превратить API JavaScript в более стабильный и логичный, + он меньше фокусируется на том, чтобы предоставить вам интерфейс, который "изменит то, как вы обычно пишете + JavaScript", а больше на том, чтобы сделать JavaScript в целом менее мучительным в использовании. + MooTools — это расширение языка JavaScript. Он пытается сделать из JavaScript то, чем он должен + быть. Значительная часть ядра библиотеки посвящена расширению Function, String, Array, Number, + Element и других прототипов. Также, очень важная часть — функция Class. +

      +

      + Class для многих людей выглядит так, как будто мы попытались воссоздать более классическое + наследование, как в Java или C++, но + это не так. + Основная задача Class — сделать модель прототипного наследования более простой + в использовании. Замечу, что этот подход есть не только в MooTools, другие фреймворки предлагают + похожую функциональность, но в jQuery этого нет. jQuery не предлагает ни системы наследования, + ни расширений для обычных объектов (Function, String и т.п.). Это не недостаток jQuery, так как его + авторы легко могли бы добавить такую функциональность, но они разрабатывали библиотеку совершенно + с другой целью. В то время как MooTools стремится сделать JavaScript более крутым, jQuery делает + DOM более крутым, и его разработчики решили ограничить масштаб проекта только этой задачей. +

      + + +

      jQuery Makes the DOM More Fun

      + +

      + And this is why jQuery is more accessible. It doesn't ask that you learn JavaScript inside and out. It doesn't throw you into the deep end with prototypal inheritance, binding, "this", and native prototypes. When you get started with jQuery in its official tutorial, this is the first jQuery code example you find: +

      +
      window.onload = function() {
           alert("welcome");
       }
      -

      and here's the third:

      +

      and here's the third:

      $(document).ready(function() {
           $("a").click(function(event) {
      @@ -461,43 +510,43 @@ 

      jQuery Makes the DOM More Fun

      }); });
      -

      - If you read the MooTools book or the MooTools tutorial (both of which I authored) they start in a much different place. While you can skip ahead and quickly learn about effects and the DOM, if you want to learn MooTools, you have to start with things like Class, and, I'll admit: if you're new to programming, or you just want to get something working on your site without having to learn everything about JavaScript, chances are jQuery is going to look a lot more friendly to you. -

      - -

      - On the other hand, if you want to learn JavaScript itself, MooTools is a great way to do it. It implements a lot of things that JavaScript is going to have (many of the methods on Natives are just the JavaScript 1.8 spec and beyond). If you're used to programming, especially both object oriented and functional programming, MooTools has a lot of design patterns that are very exciting and expressive. -

      - - -

      Anything You Can Do I Can Do Better

      - -

      - If you look at the things jQuery can do, there's often a counterpart in MooTools. If you look at the things MooTools can do, there is often no way to emulate it using jQuery code because of jQuery's focus on the DOM. MooTools has a broader functionality than jQuery, but there's nothing about jQuery that prevents you from doing those things. For example, jQuery does not come with any sort of inheritance system, but that's ok. You could, if you want, use the MooTools Class in conjunction with jQuery if you wanted to (or write your own). There's even an inheritance plug-in for jQuery (I haven't used it, but I assume it offers pretty much the same kind of functionality). -

      - -

      If we look at the example from jQuery above:

      - +

      + If you read the MooTools book or the MooTools tutorial (both of which I authored) they start in a much different place. While you can skip ahead and quickly learn about effects and the DOM, if you want to learn MooTools, you have to start with things like Class, and, I'll admit: if you're new to programming, or you just want to get something working on your site without having to learn everything about JavaScript, chances are jQuery is going to look a lot more friendly to you. +

      + +

      + On the other hand, if you want to learn JavaScript itself, MooTools is a great way to do it. It implements a lot of things that JavaScript is going to have (many of the methods on Natives are just the JavaScript 1.8 spec and beyond). If you're used to programming, especially both object oriented and functional programming, MooTools has a lot of design patterns that are very exciting and expressive. +

      + + +

      Anything You Can Do I Can Do Better

      + +

      + If you look at the things jQuery can do, there's often a counterpart in MooTools. If you look at the things MooTools can do, there is often no way to emulate it using jQuery code because of jQuery's focus on the DOM. MooTools has a broader functionality than jQuery, but there's nothing about jQuery that prevents you from doing those things. For example, jQuery does not come with any sort of inheritance system, but that's ok. You could, if you want, use the MooTools Class in conjunction with jQuery if you wanted to (or write your own). There's even an inheritance plug-in for jQuery (I haven't used it, but I assume it offers pretty much the same kind of functionality). +

      + +

      If we look at the example from jQuery above:

      +
      $(document).ready(function() {
           $("a").click(function(event) {
               alert("Thanks for visiting!");
           });
       });
      - -

      - and we wanted to translate this to MooTools, we'd have: -

      + +

      + and we wanted to translate this to MooTools, we'd have: +

      window.addEvent('domready', function() {
           $$('a').addEvent('click', function(event) {
               alert('Thanks for visiting!');
           });
       });
      -

      - These are very similar no? -

      -

      - Here's a more complex example from jQuery: -

      +

      + These are very similar no? +

      +

      + Here's a more complex example from jQuery: +

      $(document).ready(function() {
           $("#orderedlist li:last").hover(function() {
      @@ -508,9 +557,9 @@ 

      Anything You Can Do I Can Do Better

      }); });
      -

      - and in MooTools: -

      +

      + and in MooTools: +

      window.addEvent('domready',function() {
           $$('#orderedlist li:last-child').addEvents({
      @@ -523,19 +572,19 @@ 

      Anything You Can Do I Can Do Better

      }); });
      -

      - Again, very similar. I'd argue that the MooTools version is more explicit, but also more verbose because of it. It's clear reading the MooTools code that we're adding two events - one for mouse enter and one on mouse leave, while the jQuery version is more concise; its hover method accepts two methods - the first for mouse enter and the second for mouse leave. I personally like the fact that the MooTools code is more legible but that's a very subjective observation. -

      - -

      - I will say that sometimes jQuery can become too esoteric for my taste. The methods don't always make sense to me just looking at them and I find it hard to parse. This is somewhat unfair though, as I am intimately familiar with MooTools, so reading MooTools is easy for me. But one of the things I appreciate about MooTools is how almost all the method and class names really name the thing. Methods are almost always verbs and leave little doubt as to what they do. Every programming language requires you to go to the docs to look up syntax when you write it - I'm not saying that. I'm just saying that I find the API of MooTools to be more coherent and consistent. -

      - - -

      MooTools Lets You Have It Your Way

      - -

      But what if you like the jQuery syntax? One way to illustrate the power of MooTools is to show you how easy it is to change it to suit your tastes. If we wanted to implement the hover method from jQuery in MooTools, we could easily do so:

      - +

      + Again, very similar. I'd argue that the MooTools version is more explicit, but also more verbose because of it. It's clear reading the MooTools code that we're adding two events - one for mouse enter and one on mouse leave, while the jQuery version is more concise; its hover method accepts two methods - the first for mouse enter and the second for mouse leave. I personally like the fact that the MooTools code is more legible but that's a very subjective observation. +

      + +

      + I will say that sometimes jQuery can become too esoteric for my taste. The methods don't always make sense to me just looking at them and I find it hard to parse. This is somewhat unfair though, as I am intimately familiar with MooTools, so reading MooTools is easy for me. But one of the things I appreciate about MooTools is how almost all the method and class names really name the thing. Methods are almost always verbs and leave little doubt as to what they do. Every programming language requires you to go to the docs to look up syntax when you write it - I'm not saying that. I'm just saying that I find the API of MooTools to be more coherent and consistent. +

      + + +

      MooTools Lets You Have It Your Way

      + +

      But what if you like the jQuery syntax? One way to illustrate the power of MooTools is to show you how easy it is to change it to suit your tastes. If we wanted to implement the hover method from jQuery in MooTools, we could easily do so:

      +
      Element.implement({
           hover : function(enter,leave){
              return this.addEvents({ mouseenter : enter, mouseleave : leave });
      @@ -551,14 +600,14 @@ 

      MooTools Lets You Have It Your Way

      });
      -

      Indeed, there are MooTools plug-ins that do just that; give you the jQuery syntax for MooTools. MooTools' focus on extensibility means you can implement anything you like. This is something jQuery can't do. MooTools can mimic jQuery if you want it to, but jQuery can't mimic MooTools. If you want to write classes or extend native prototypes or do some of the other things MooTools can, you'll have to write it yourself.

      - - -

      Chaining as a Design Pattern

      - -

      - Let's do another of these. Here's some jQuery (from the jQuery tutorial): -

      +

      Indeed, there are MooTools plug-ins that do just that; give you the jQuery syntax for MooTools. MooTools' focus on extensibility means you can implement anything you like. This is something jQuery can't do. MooTools can mimic jQuery if you want it to, but jQuery can't mimic MooTools. If you want to write classes or extend native prototypes or do some of the other things MooTools can, you'll have to write it yourself.

      + + +

      Chaining as a Design Pattern

      + +

      + Let's do another of these. Here's some jQuery (from the jQuery tutorial): +

      $(document).ready(function() {
           $('#faq').find('dd').hide().end().find('dt').click(function() {
      @@ -566,12 +615,12 @@ 

      Chaining as a Design Pattern

      }); });
      -

      - This is an example of a syntax that I personally don't prefer. Looking at the code above I am hard pressed to be sure of what it's doing. Most notably I'm curious about what .end does and how does .find, which follows it, relate to what .end does? Now, looking at the docs on jQuery makes it very clear what .end does (it resets to the value of the original selector, in this case #faq). But this seems very odd to me. When I do work with jQuery, I often find myself unsure what a method is going to return to me. Obviously this doesn't bother everyone else as jQuery has a lot of people happily using it, so I'll chalk it up to personal preference again. -

      -

      - Let's look at the above logic as MooTools: -

      +

      + This is an example of a syntax that I personally don't prefer. Looking at the code above I am hard pressed to be sure of what it's doing. Most notably I'm curious about what .end does and how does .find, which follows it, relate to what .end does? Now, looking at the docs on jQuery makes it very clear what .end does (it resets to the value of the original selector, in this case #faq). But this seems very odd to me. When I do work with jQuery, I often find myself unsure what a method is going to return to me. Obviously this doesn't bother everyone else as jQuery has a lot of people happily using it, so I'll chalk it up to personal preference again. +

      +

      + Let's look at the above logic as MooTools: +

      window.addEvent('domready', function() {
           var faq = $('faq');
      @@ -583,30 +632,30 @@ 

      Chaining as a Design Pattern

      -

      - Again, the MooTools code is a bit more verbose, but also more explicit. Also note that the design pattern here is to store the reference to #faq in a variable, where jQuery uses its .end method to return to it. I'll note that it's possible to write highly chained code with Mootools. For example: -

      +

      + Again, the MooTools code is a bit more verbose, but also more explicit. Also note that the design pattern here is to store the reference to #faq in a variable, where jQuery uses its .end method to return to it. I'll note that it's possible to write highly chained code with Mootools. For example: +

      item.getElements('input[type=checkbox]')
      -	.filter(function(box) {
      -		return box.checked != checked;
      -	})
      -	.set('checked', checked)
      -	.getParent()[(checked) ? 'addClass' : 'removeClass']('checked')
      -	.fireEvent((checked) ? 'check' : 'uncheck');
      - -

      - But really, writing code like this - lots of logic in a domready statement - with either framework, I'd argue, is itself a bad practice. It's far better to encapsulate your logic into reusable chunks. -

      - - -

      Reusing Code with jQuery

      - -

      - It's very tempting when you're working on a web project to write code this way. Just add some logic on the page that selects the DOM elements and "sets them up" by hiding some, altering others, and adding event listeners for click or mouseover. Developing code this way is very efficient, very fast. The problem with writing all your logic in domready statements is that you end up with a lot of code that does the same thing in different places. If we take the FAQ pattern above we could easily apply the same logic elsewhere on a different page with any list of terms and definitions. Are we going to repeat the same logic every time we find this pattern? -

      -

      - A simple way to make it reusable is to wrap the logic in a function and pass in arguments. Here's what that might look like in jQuery: -

      + .filter(function(box) { + return box.checked != checked; + }) + .set('checked', checked) + .getParent()[(checked) ? 'addClass' : 'removeClass']('checked') + .fireEvent((checked) ? 'check' : 'uncheck'); + +

      + But really, writing code like this - lots of logic in a domready statement - with either framework, I'd argue, is itself a bad practice. It's far better to encapsulate your logic into reusable chunks. +

      + + +

      Reusing Code with jQuery

      + +

      + It's very tempting when you're working on a web project to write code this way. Just add some logic on the page that selects the DOM elements and "sets them up" by hiding some, altering others, and adding event listeners for click or mouseover. Developing code this way is very efficient, very fast. The problem with writing all your logic in domready statements is that you end up with a lot of code that does the same thing in different places. If we take the FAQ pattern above we could easily apply the same logic elsewhere on a different page with any list of terms and definitions. Are we going to repeat the same logic every time we find this pattern? +

      +

      + A simple way to make it reusable is to wrap the logic in a function and pass in arguments. Here's what that might look like in jQuery: +

      function faq(container, terms, definitions) {
           $(container).find(terms).hide().end().find(definitions).click(function() {
      @@ -617,55 +666,55 @@ 

      Reusing Code with jQuery

      faq('#faq', 'dd', 'dt'); });
      -

      - This is much better for two really big and important reasons: -

      -
        -
      1. - If tomorrow we need to change how these lists work (maybe we want to add click tracking logic so we can measure it in our web logs or maybe we want to fetch the definitions via ajax) we can just change our main faq method and everywhere we use it just gets updated. Or if there's a new version of jQuery released that changes the way things work, we can just go update our one method instead of a dozen copies everywhere. I call this keeping a small footprint in my application. By keeping the points where my application touches my more generic code as small as possible, it makes it easier for me to fix bugs, upgrade frameworks, add features, or alter functionality. -
      2. -
      3. - The second reason is that it's less code. By reusing the same method over and over again, I don't repeat myself and this is valuable in any programming environment. It also makes the code my visitors have to download smaller. -
      4. -
      -

      - jQuery actually has a slightly more refined system for writing reusable "widgets" like these. Rather than encourage you to drop them into functions like the above example (which is really rather crude) it encourages you to write jQuery plug-ins. Here's what that would look like: +

      + This is much better for two really big and important reasons: +

      +
        +
      1. + If tomorrow we need to change how these lists work (maybe we want to add click tracking logic so we can measure it in our web logs or maybe we want to fetch the definitions via ajax) we can just change our main faq method and everywhere we use it just gets updated. Or if there's a new version of jQuery released that changes the way things work, we can just go update our one method instead of a dozen copies everywhere. I call this keeping a small footprint in my application. By keeping the points where my application touches my more generic code as small as possible, it makes it easier for me to fix bugs, upgrade frameworks, add features, or alter functionality. +
      2. +
      3. + The second reason is that it's less code. By reusing the same method over and over again, I don't repeat myself and this is valuable in any programming environment. It also makes the code my visitors have to download smaller. +
      4. +
      +

      + jQuery actually has a slightly more refined system for writing reusable "widgets" like these. Rather than encourage you to drop them into functions like the above example (which is really rather crude) it encourages you to write jQuery plug-ins. Here's what that would look like:

      jQuery.fn.faq = function(options) {
           var settings = jQuery.extend({
               terms: 'dt',
               definitions: 'dd'
           }, options); 
      -	//"this" is the current context; in this case, the elements we want to turn into faq layouts
      +    //"this" is the current context; in this case, the elements we want to turn into faq layouts
           $(this).find(settings.terms).hide().end().find(settings.definitions).click(function() {
               $(this).next().slideToggle();
           });
           return this;
       };
      -

      - which you would use thusly: -

      -
      $('#faq').faq();
      +

      + which you would use thusly: +

      +
      $('#faq').faq();
      -

      - But looking at the example above, there's not much difference between declaring our faq function this way vs. declaring it as a stand alone function. Granted, it's not in the global namespace, but we could have just as easily added it to a namespace of our own. By attaching it to jQuery we can chain it with other jquery methods. The other benefit is that the "this" inside our function is the current context of whatever is in the jQuery chain at that moment. By using this pattern for plug-ins we're able to make our plug-in look like it's part of jQuery, but other than that, our plug-in is basically a single function that takes the current jQuery context, does stuff to it, and then returns the context for the next item in the chain. There's not a lot of complexity here, which makes it easy for anyone to write jQuery plug-ins - they're just single functions. -

      +

      + But looking at the example above, there's not much difference between declaring our faq function this way vs. declaring it as a stand alone function. Granted, it's not in the global namespace, but we could have just as easily added it to a namespace of our own. By attaching it to jQuery we can chain it with other jquery methods. The other benefit is that the "this" inside our function is the current context of whatever is in the jQuery chain at that moment. By using this pattern for plug-ins we're able to make our plug-in look like it's part of jQuery, but other than that, our plug-in is basically a single function that takes the current jQuery context, does stuff to it, and then returns the context for the next item in the chain. There's not a lot of complexity here, which makes it easy for anyone to write jQuery plug-ins - they're just single functions. +

      -

      - Note that it is possible to write more complex plugins with jQuery with methods and state. This kind of pattern is supported with the jQuery UI plugin system and doesn't use the same mechanism as the basic plugin (like our faq example). Instead, you attach an object with methods and properties to the jQuery object (i.e. $.ui.tabs). There's a shortcut to invoke this object ($(selector).tabs()) so that you can continue chaining as with the faq plugin. But because it doesn't return a reference to the tabs object created for the items in your selector, you're forced to call that selector again to invoke methods on it. Instead of calling myTabInstance.add(url, label, index) you must execute the selector again and call your function by name (as a string): $(selector).tabs('add', url, label, index);. This means you're running your selector twice (unless you store it in a variable somewhere), and that you don't ever have a pointer to the "add" method that you can do things like bind or delay. This post is focused on the MooTools and jQuery cores, and while jQuery's UI system does provide this functionality, it's not something that comes with jQuery by default. -

      +

      + Note that it is possible to write more complex plugins with jQuery with methods and state. This kind of pattern is supported with the jQuery UI plugin system and doesn't use the same mechanism as the basic plugin (like our faq example). Instead, you attach an object with methods and properties to the jQuery object (i.e. $.ui.tabs). There's a shortcut to invoke this object ($(selector).tabs()) so that you can continue chaining as with the faq plugin. But because it doesn't return a reference to the tabs object created for the items in your selector, you're forced to call that selector again to invoke methods on it. Instead of calling myTabInstance.add(url, label, index) you must execute the selector again and call your function by name (as a string): $(selector).tabs('add', url, label, index);. This means you're running your selector twice (unless you store it in a variable somewhere), and that you don't ever have a pointer to the "add" method that you can do things like bind or delay. This post is focused on the MooTools and jQuery cores, and while jQuery's UI system does provide this functionality, it's not something that comes with jQuery by default. +

      - -

      Reusing Code with MooTools

      + +

      Reusing Code with MooTools

      -

      - In MooTools when you want to define a pattern, you're more likely to use either a Class or implement a method into a native object (into String, for example). -

      - -

      - Rather than give you an almost completely different language from JavaScript's native style, MooTools attempts to walk the middle ground between defining its own custom syntax and extending JavaScript's own design patterns. One of the ways it does this is by extending the prototypes of the native objects in the language and in the DOM. This means that if you needed a method to trim a string, MooTools encourages you to add that method to String itself (note that String.trim is already in MooTools; you don't need to add this yourself): -

      +

      + In MooTools when you want to define a pattern, you're more likely to use either a Class or implement a method into a native object (into String, for example). +

      + +

      + Rather than give you an almost completely different language from JavaScript's native style, MooTools attempts to walk the middle ground between defining its own custom syntax and extending JavaScript's own design patterns. One of the ways it does this is by extending the prototypes of the native objects in the language and in the DOM. This means that if you needed a method to trim a string, MooTools encourages you to add that method to String itself (note that String.trim is already in MooTools; you don't need to add this yourself): +

      String.implement({
           trim: function() {
      @@ -673,50 +722,50 @@ 

      Reusing Code with MooTools

      } });
      -

      - This means you can just execute " no more spaces on the end! ".trim() and get back "no more spaces on the end!". Some would say that implementing properties into native prototypes is inappropriate. It's the reason why MooTools and Prototype.js can't play well with each other - any framework that manipulates prototypes of natives doesn't play well with any other framework that does the same. If I define String.prototype.foo() and another library on the same page defines it, too, which ever one comes last wins. In a way, this is similar to the problem we face with the global window namespace. This is how JavaScript works. This is how JavaScript 1.8 has added so many features. It adds them to the prototypes. -

      -

      - The MooTools developers include a robust framework that is easy for you to extend with your own functionality with the intention that people who include the framework in the page are going to use it, not some other framework. It's actually kind of rude to ask users to download two frameworks. The only reason to include two frameworks is because you want to use plug-ins from both, and in the minds of the MooTools authors (myself included), if you want a plug-in that isn't available with the framework of your choice, it's more appropriate for you to spend the time porting it to your environment than to ask your users to download another framework. -

      -

      - Once you learn how JavaScript works and see the power of extending native objects, a whole new level of programming opens up. You can write plug-ins that alter Elements or Dates or Functions. While some might argue that adding methods to natives this way is a kind of pollution, I'd argue that this is how JavaScript is meant to be used. It is a design feature of the language. By attaching methods to natives you allow your code to be concise and compartmentalized. jQuery does this too, but limits its prototype enhancements to the jQuery object. -

      - -

      - While you can easily chain multiple method calls on the jQuery object, on any other type of object you have to use - generics. For example, in jQuery if you want to trim a string and then iterate over each line, you would have to write: -

      - -
      $.each( $.trim( $('span.something').html() ).split("\n"), function(i, line){alert(line);});
      - -

      But because MooTools modifies prototypes, you can do this:

      - -
      $('span.something').get('html').trim().split("\n").each(function(line){alert(line);});
      - -

      - Taking a look at this makes it extremely clear how powerful it is to - modify prototypes. Chaining on DOM elements isn't the only place chaining is - useful. MooTools lets you chain methods on any object, including - running a method on multiple elements at once. -

      - -

      - The key here is that at the heart of the MooTools framework is the notion that it's there to let you program what you want. If there's functionality that's not in the core, you can extend it and add your own. The job of the core is not to provide everyone with every bit of functionality that they could ever want, but to provide the tools that allow you write the things that you want. A big part of that is making it easier to extend the prototypes of natives, and take advantage of prototypal inheritance. You can do these things with vanilla JavaScript but MooTools makes it easier and more pleasant. - -

      - - - -

      MooTools and Inheritance

      - -

      - Despite its name, the MooTools Class function is not really a class nor does it create them. It has design patterns that might remind you of classes in a more traditional programming language, but really Class is all about objects and prototypal inheritance. (Unfortunately, using words like "class" are the most convenient way to describe these things, so for the purposes of this article, when I refer to "classes" I'm referring to functions that return objects - which I'll call "instances" - that inherit from a prototype.) -

      -

      - To make a class, you pass an object to the Class constructor like this: -

      - +

      + This means you can just execute " no more spaces on the end! ".trim() and get back "no more spaces on the end!". Some would say that implementing properties into native prototypes is inappropriate. It's the reason why MooTools and Prototype.js can't play well with each other - any framework that manipulates prototypes of natives doesn't play well with any other framework that does the same. If I define String.prototype.foo() and another library on the same page defines it, too, which ever one comes last wins. In a way, this is similar to the problem we face with the global window namespace. This is how JavaScript works. This is how JavaScript 1.8 has added so many features. It adds them to the prototypes. +

      +

      + The MooTools developers include a robust framework that is easy for you to extend with your own functionality with the intention that people who include the framework in the page are going to use it, not some other framework. It's actually kind of rude to ask users to download two frameworks. The only reason to include two frameworks is because you want to use plug-ins from both, and in the minds of the MooTools authors (myself included), if you want a plug-in that isn't available with the framework of your choice, it's more appropriate for you to spend the time porting it to your environment than to ask your users to download another framework. +

      +

      + Once you learn how JavaScript works and see the power of extending native objects, a whole new level of programming opens up. You can write plug-ins that alter Elements or Dates or Functions. While some might argue that adding methods to natives this way is a kind of pollution, I'd argue that this is how JavaScript is meant to be used. It is a design feature of the language. By attaching methods to natives you allow your code to be concise and compartmentalized. jQuery does this too, but limits its prototype enhancements to the jQuery object. +

      + +

      + While you can easily chain multiple method calls on the jQuery object, on any other type of object you have to use + generics. For example, in jQuery if you want to trim a string and then iterate over each line, you would have to write: +

      + +
      $.each( $.trim( $('span.something').html() ).split("\n"), function(i, line){alert(line);});
      + +

      But because MooTools modifies prototypes, you can do this:

      + +
      $('span.something').get('html').trim().split("\n").each(function(line){alert(line);});
      + +

      + Taking a look at this makes it extremely clear how powerful it is to + modify prototypes. Chaining on DOM elements isn't the only place chaining is + useful. MooTools lets you chain methods on any object, including + running a method on multiple elements at once. +

      + +

      + The key here is that at the heart of the MooTools framework is the notion that it's there to let you program what you want. If there's functionality that's not in the core, you can extend it and add your own. The job of the core is not to provide everyone with every bit of functionality that they could ever want, but to provide the tools that allow you write the things that you want. A big part of that is making it easier to extend the prototypes of natives, and take advantage of prototypal inheritance. You can do these things with vanilla JavaScript but MooTools makes it easier and more pleasant. + +

      + + + +

      MooTools and Inheritance

      + +

      + Despite its name, the MooTools Class function is not really a class nor does it create them. It has design patterns that might remind you of classes in a more traditional programming language, but really Class is all about objects and prototypal inheritance. (Unfortunately, using words like "class" are the most convenient way to describe these things, so for the purposes of this article, when I refer to "classes" I'm referring to functions that return objects - which I'll call "instances" - that inherit from a prototype.) +

      +

      + To make a class, you pass an object to the Class constructor like this: +

      +
      var Human = new Class({
           initialize: function(name, age) {
               this.name = name;
      @@ -728,57 +777,57 @@ 

      MooTools and Inheritance

      this.energy = this.energy + 1; //same as this.energy++ } });
      - -

      - You pass Class an object (above, we pass an object with members like "isAlive" and "eat") and this object becomes the prototype of every instance of that class. To create an instance, you call it like this: -

      + +

      + You pass Class an object (above, we pass an object with members like "isAlive" and "eat") and this object becomes the prototype of every instance of that class. To create an instance, you call it like this: +

      var bob = new Human("bob", 20); //bob's name is "bob" and he's 20 years old.
      -

      - Now we have an instance of Human. bob has the properties of the object we defined when we created our Human class. But the important thing is that bob has these properties through inheritance. When we reference bob.eat, bob doesn't really have this property. JavaScript looks at bob and he doesn't have an eat method, so it looks up the inheritance chain and finds it on the object we passed when we created the Human class. This is true for energy, too. At first glance this looks potentially bad; we don't want all the humans we create to gain energy every time that bob eats. The important thing to recognize is that the first time we assign a value to bob's energy, we assign him his own value and we no longer look at the prototype for it. So the first time bob eats, he gets his own definition for energy (set to 2). -

      -
      bob.eat(); //bob.energy == 2
      -

      - Note that bob's name and age are unique to him; these are assigned to him when the class is initialized in the initialize method. -

      -

      - This whole pattern may seem a little odd to you, but the value here is that we can define functionality for a pattern and create instances of that pattern every time we need it. Each instance maintains its own state. So if we create another instance each one is independent of the other, but inherits from the same base pattern: -

      - +

      + Now we have an instance of Human. bob has the properties of the object we defined when we created our Human class. But the important thing is that bob has these properties through inheritance. When we reference bob.eat, bob doesn't really have this property. JavaScript looks at bob and he doesn't have an eat method, so it looks up the inheritance chain and finds it on the object we passed when we created the Human class. This is true for energy, too. At first glance this looks potentially bad; we don't want all the humans we create to gain energy every time that bob eats. The important thing to recognize is that the first time we assign a value to bob's energy, we assign him his own value and we no longer look at the prototype for it. So the first time bob eats, he gets his own definition for energy (set to 2). +

      +
      bob.eat(); //bob.energy == 2
      +

      + Note that bob's name and age are unique to him; these are assigned to him when the class is initialized in the initialize method. +

      +

      + This whole pattern may seem a little odd to you, but the value here is that we can define functionality for a pattern and create instances of that pattern every time we need it. Each instance maintains its own state. So if we create another instance each one is independent of the other, but inherits from the same base pattern: +

      +
      var Alice = new Human();
       //alice.energy == 1
       //bob.energy == 2
      - -

      - Where things get really interesting is when we want to augment this behavior. -

      - - -

      Extending and Implementing Classes

      - -

      - Let's revisit our jQuery faq plug-in. What would happen if we wanted to add more functionality to that plug-in. What if we wanted to make an ajax version that fetched the answers to the questions from the server? Let's imagine that the faq plug-in was authored by someone else and we want to add more to it without altering it in any way (we don't want to fork it). -

      -

      - Our only real choices are to either duplicate the faq plug-in's logic entirely (remember, it's a single function), essentially forking it, or we can invoke it and then add more logic to it. Given a choice, the latter seems to save us the most trouble. It would look something like this: -

      + +

      + Where things get really interesting is when we want to augment this behavior. +

      + + +

      Extending and Implementing Classes

      + +

      + Let's revisit our jQuery faq plug-in. What would happen if we wanted to add more functionality to that plug-in. What if we wanted to make an ajax version that fetched the answers to the questions from the server? Let's imagine that the faq plug-in was authored by someone else and we want to add more to it without altering it in any way (we don't want to fork it). +

      +

      + Our only real choices are to either duplicate the faq plug-in's logic entirely (remember, it's a single function), essentially forking it, or we can invoke it and then add more logic to it. Given a choice, the latter seems to save us the most trouble. It would look something like this: +

      jQuery.fn.ajaxFaq = function(options) {
           var settings = jQuery.extend({ 
      -		//some ajax specific options like the url to request terms from
      +        //some ajax specific options like the url to request terms from
               url: '/getfaq.php'
               definitions: 'dd'
           }, options); 
      -	//"this" is the current context; in this case, the elements we want to turn into faq layouts
      +    //"this" is the current context; in this case, the elements we want to turn into faq layouts
           $(this).find(settings.definitions).click(function() {
               $(this).load(.....); //the logic to load the content from the term
           });
           this.faq(); //call our original faq plug-in
       });
      -

      - This has some down sides. First of all, our faq class is going to repeat our selector for the definitions, which might be expensive; there's no way to store the retrieved definitions and pass it on for the second time they are needed. Secondly, we can't add our ajax logic into the middle of the faq plug-in's own logic for displaying the definition. The original plug-in called slideToggle which expands the definition using an effect. This is problematic because this effect is going to go off before our ajax finishes loading. There's no real solution here unless we just duplicate the entire faq plug-in. -

      -

      - Now let's consider our MooTools Human class. It has properties like isAlive and energy and it has a method called eat. What if we wanted to make a new version of Human that had additional properties? With MooTools, we extend the class: -

      +

      + This has some down sides. First of all, our faq class is going to repeat our selector for the definitions, which might be expensive; there's no way to store the retrieved definitions and pass it on for the second time they are needed. Secondly, we can't add our ajax logic into the middle of the faq plug-in's own logic for displaying the definition. The original plug-in called slideToggle which expands the definition using an effect. This is problematic because this effect is going to go off before our ajax finishes loading. There's no real solution here unless we just duplicate the entire faq plug-in. +

      +

      + Now let's consider our MooTools Human class. It has properties like isAlive and energy and it has a method called eat. What if we wanted to make a new version of Human that had additional properties? With MooTools, we extend the class: +

      var Ninja = new Class({
           Extends: Human,
           initialize: function(name, age, side) {
      @@ -791,9 +840,9 @@ 

      Extending and Implementing Classes

      target.isAlive = false; } });
      -

      - You can see that we've added a lot of functionality here into a subclass. This subclass has all these properties that are unique to Ninjas. Ninjas start off with an initial energy value of 100. Ninjas get a side. They also get an attack method that lets them kill other Humans, but it costs the Ninja energy. -

      +

      + You can see that we've added a lot of functionality here into a subclass. This subclass has all these properties that are unique to Ninjas. Ninjas start off with an initial energy value of 100. Ninjas get a side. They also get an attack method that lets them kill other Humans, but it costs the Ninja energy. +

      var bob = new Human('Bob', 25);
       var blackNinja = new Ninja('Nin Tendo', 'unknown', 'evil');
      @@ -802,15 +851,15 @@ 

      Extending and Implementing Classes

      blackNinja.attack(bob); //bob never had a chance
      -

      - Picking this apart a bit, there are some interesting things to consider here. Note that we have an initialize method in the Ninja class. This would appear to overwrite the initialize method in the Human class, but we can still access it by calling this.parent, passing along the arguments that the parent class's initialize expects. Further, we can control when our logic occurs; before or after the call to the parent. We can assign new values to properties (like the energy value) and we can define new functionality. Imagine if we could do this with our faq plug-in for jQuery. We could load our ajax and THEN slide open the value. -

      -

      - MooTools has another pattern called a Mixin. Unlike the parent to - child relationship that is defined by extending one class into a - subclass, you can also define classes that are mixed into other - classes to imbue them with their properties. Here's an example: -

      +

      + Picking this apart a bit, there are some interesting things to consider here. Note that we have an initialize method in the Ninja class. This would appear to overwrite the initialize method in the Human class, but we can still access it by calling this.parent, passing along the arguments that the parent class's initialize expects. Further, we can control when our logic occurs; before or after the call to the parent. We can assign new values to properties (like the energy value) and we can define new functionality. Imagine if we could do this with our faq plug-in for jQuery. We could load our ajax and THEN slide open the value. +

      +

      + MooTools has another pattern called a Mixin. Unlike the parent to + child relationship that is defined by extending one class into a + subclass, you can also define classes that are mixed into other + classes to imbue them with their properties. Here's an example: +

      var Warrior = new Class({
           energy: 100,
      @@ -822,9 +871,9 @@ 

      Extending and Implementing Classes

      } });
      -

      - Here we've broken the qualities that make a Ninja different from a Human and put them in a class of their own. This lets us reuse this code outside of Ninja. We could then imbue our Ninja class with the qualities of a warrior like so: -

      +

      + Here we've broken the qualities that make a Ninja different from a Human and put them in a class of their own. This lets us reuse this code outside of Ninja. We could then imbue our Ninja class with the qualities of a warrior like so: +

      var Ninja = new Class({
           Extends: Human,
      @@ -834,10 +883,10 @@ 

      Extending and Implementing Classes

      this.parent(name, age); } });
      - -

      - Ninja still works as it did before, but Warrior is at our disposal to reuse: -

      + +

      + Ninja still works as it did before, but Warrior is at our disposal to reuse: +

      var Samurai = new Class({
         Extends: Human,
      @@ -845,166 +894,166 @@ 

      Extending and Implementing Classes

      side: 'good' });
      -

      - Now we have a Samurai class and a Ninja class. But look at how little code both Ninja and Samurai took to define. Both of them are similar in that they are humans with warrior qualities, but they are different in that samurais are always, always good, while ninjas have shifting allegiances. By spending the time to write a Human class and a Warrior class, we're able to have three different classes with no repetition of code while maintaining a very granular level of control over when methods are called and how they relate to each other. Each instance we create has its own state and the code itself is very legible. -

      - -

      - Now that you have an overview of how classes work in MooTools, let's look at our faq class that we wrote in jQuery and write it as we would in MooTools and then extend it to add Ajax to it just as we did with jQuery. -

      +

      + Now we have a Samurai class and a Ninja class. But look at how little code both Ninja and Samurai took to define. Both of them are similar in that they are humans with warrior qualities, but they are different in that samurais are always, always good, while ninjas have shifting allegiances. By spending the time to write a Human class and a Warrior class, we're able to have three different classes with no repetition of code while maintaining a very granular level of control over when methods are called and how they relate to each other. Each instance we create has its own state and the code itself is very legible. +

      + +

      + Now that you have an overview of how classes work in MooTools, let's look at our faq class that we wrote in jQuery and write it as we would in MooTools and then extend it to add Ajax to it just as we did with jQuery. +

       var FAQ = new Class({
      -	//Options is another class provided by MooTools
      -	Implements: Options,
      -	//these are the default options
      -	options: {
      -		terms: 'dt',
      -		definitions: 'dd'
      -	},
      -	initialize: function(container, options) {
      -		//we store a reference to our container
      -		this.container = $(container);
      -		//setOptions is a method provided by the Options mixin
      -		//it merges the options passed in with the defaults
      -		this.setOptions(options);
      -		//we store the terms and definitions
      -		this.terms = this.container.getElements(this.options.terms);
      -		this.definitions = this.container.getElements(this.options.definitions);
      -		//we call our attach method
      -		//by breaking this into its own method
      -		//it makes our class easier to extend
      -		this.attach();
      -	},
      -	attach: function(){
      -		//loop through the terms
      -		this.terms.each(function(term, index) {
      -			//add a click event to each one
      -			term.addEvent('click', function(){
      -				//that calls our toggle method for
      -				//the current index
      -				this.toggle(index);
      -			}, this);
      -		}, this);
      -	},
      -	toggle: function(index){
      -		//toggle open the definition for the given index
      -		this.definitions[index].slide('toggle');
      -	}
      +    //Options is another class provided by MooTools
      +    Implements: Options,
      +    //these are the default options
      +    options: {
      +        terms: 'dt',
      +        definitions: 'dd'
      +    },
      +    initialize: function(container, options) {
      +        //we store a reference to our container
      +        this.container = $(container);
      +        //setOptions is a method provided by the Options mixin
      +        //it merges the options passed in with the defaults
      +        this.setOptions(options);
      +        //we store the terms and definitions
      +        this.terms = this.container.getElements(this.options.terms);
      +        this.definitions = this.container.getElements(this.options.definitions);
      +        //we call our attach method
      +        //by breaking this into its own method
      +        //it makes our class easier to extend
      +        this.attach();
      +    },
      +    attach: function(){
      +        //loop through the terms
      +        this.terms.each(function(term, index) {
      +            //add a click event to each one
      +            term.addEvent('click', function(){
      +                //that calls our toggle method for
      +                //the current index
      +                this.toggle(index);
      +            }, this);
      +        }, this);
      +    },
      +    toggle: function(index){
      +        //toggle open the definition for the given index
      +        this.definitions[index].slide('toggle');
      +    }
       });
       
      -

      - Woah. That's a lot of code. Even if we remove all the comments it's still two dozen lines long. I already illustrated above that we could build this plug-in with roughly the same amount of code as the jQuery version. So why is this one so much longer? Well, we've made it much more flexible. To use the class, we just call the constructor, like this: -

      +

      + Woah. That's a lot of code. Even if we remove all the comments it's still two dozen lines long. I already illustrated above that we could build this plug-in with roughly the same amount of code as the jQuery version. So why is this one so much longer? Well, we've made it much more flexible. To use the class, we just call the constructor, like this: +

      var myFAQ = new FAQ(myContainer);
       //and now we can call methods on it if we want:
       myFAQ.toggle(2); //toggle the 3rd element
       
      -

      - We can access methods and properties of the instance. But what about our ajax functionality? The problem with our ajax extension to the jQuery version was that we couldn't delay the opening of the definition until after it loaded. We don't have that problem with our MooTools version: - -

      +

      + We can access methods and properties of the instance. But what about our ajax functionality? The problem with our ajax extension to the jQuery version was that we couldn't delay the opening of the definition until after it loaded. We don't have that problem with our MooTools version: + +

      FAQ.Ajax = new Class({
      -	//this class inherits the properties of FAQ
      -	Extends: FAQ,
      -	//it also gets a new option in addition to the other defaults
      -	//this one for url, that we're going to append the index of the
      -	//term to; in reality we might make this more robust, but for
      -	//this example it serves the purpose
      -	options: {
      -		url: null;
      -	},
      -	//we're going to cache the results, so if a section is opened
      -	//twice, we won't hit the server for the data
      -	indexesLoaded: [],
      -	toggle: function(index){
      -		//if we've already loaded the definition
      -		if (this.indexesLoaded[index]) {
      -			//just call the previous version of toggle
      -			this.parent(index);
      -		} else {
      -			//otherwise, request the data from the server
      -			new Request.HTML({
      -				update: this.definitions[index],
      -				url: this.options.url + index,
      -				//and when the data is loaded, expand the definition
      -				onComplete: function(){
      -					this.indexesLoaded[index] = true;
      -					this.definitions[index].slide('toggle');
      -				}.bind(this)
      -			}).send();
      -		}
      -	}
      +    //this class inherits the properties of FAQ
      +    Extends: FAQ,
      +    //it also gets a new option in addition to the other defaults
      +    //this one for url, that we're going to append the index of the
      +    //term to; in reality we might make this more robust, but for
      +    //this example it serves the purpose
      +    options: {
      +        url: null;
      +    },
      +    //we're going to cache the results, so if a section is opened
      +    //twice, we won't hit the server for the data
      +    indexesLoaded: [],
      +    toggle: function(index){
      +        //if we've already loaded the definition
      +        if (this.indexesLoaded[index]) {
      +            //just call the previous version of toggle
      +            this.parent(index);
      +        } else {
      +            //otherwise, request the data from the server
      +            new Request.HTML({
      +                update: this.definitions[index],
      +                url: this.options.url + index,
      +                //and when the data is loaded, expand the definition
      +                onComplete: function(){
      +                    this.indexesLoaded[index] = true;
      +                    this.definitions[index].slide('toggle');
      +                }.bind(this)
      +            }).send();
      +        }
      +    }
       });
       
      -

      - Now we have a version of our FAQ class that allows us to get the definitions from the server. Note that we were able to integrate the new logic in a way that doesn't expand the definition until after the content comes back from the server (which we couldn't do with the jQuery version). Also note that we really only had to describe the new functionality (the ajax) and little else. This extensibility makes it possible for you to create families of plug-ins that offer different shades of functionality. It also means that you can use someone else's plug-in and alter just the bits that you to be want different if you need to (without forking it). This helps explain why, for any given design pattern - a date picker, a tab interface, etc, that you typically only find a few plug-ins for MooTools. Most of the plug-ins you get either solve your problem or, if not, you can just extend them to add the things you need. - -

      - -

      - As I illustrated earlier, it's possible to write complex jQuery widgets with methods and state. Most of the code you write when doing this is vanilla JavaScript when you need to express logic that isn't related to the DOM. But jQuery's model doesn't offer a system for extending these instances into subclasses. Nor does it help you with mixins that can be reused easily. Finally, jQuery's plugins are always attached to DOM elements. If you wanted to write a class that, say, processed URLs, there's no stateful system for such a thing unless you write it yourself. -

      - - -

      Decision Time

      - -

      - jQuery focuses on expressiveness, quick and easy coding, and the DOM while MooTools focuses on extension, inheritance, legibility, reuse, and maintainability. If you put those two things on opposite sides of a scale, the jQuery side translates into something with which it's easy to get started and see quick results but (in my experience) can turn into code that's harder to reuse and maintain (but really that's up to you; it's not jQuery's problem, per se), while the MooTools side takes longer to learn and requires you to write more code upfront before you see results, but afterwards is more reusable and more maintainable. -

      -

      - Further, the MooTools core does not contain every feature you can imagine and neither does the jQuery core. Both frameworks keep their cores rather lean, leaving it to you and others to write plug-ins and extensions. Their job is not to give you every feature you could want but to give you the tools so that you can implement anything you can imagine. This is the power of JavaScript, and of JavaScript frameworks in general, and both frameworks excel at it. MooTools takes a more holistic approach and gives you tools to write anything you can imagine beyond the scope of the DOM, but pays the price by having a steeper learning curve. MooTools' extensible and holistic approach gives you a superset of jQuery's features, but jQuery's focus on a slick DOM API doesn't preclude you from using the native inheritance methods of JavaScript or from using a class system like MooTools if you want it. -

      -

      - This is why I say that both frameworks are excellent choices. My effort here has been to highlight the differences in philosophies between the two codebases and highlight their advantages and disadvantages. I doubt I've been successful in keeping my preference for MooTools completely in check, but hopefully this has been helpful. Regardless of which framework you choose to work with, you now know a lot more about both, hopefully. If you have the luxury of time, I strongly recommend implementing a site with each. Then write your own review of them both and maybe your perspective will highlight some things I missed. -

      -

      A history of this document can be viewed on github.

      -

      - -

      -
      -

      - About me: I am a MooTools contributor and I blog about JavaScript and other things on my site Clientcide as well as release numerous plug-ins for MooTools. I am the author of MooTools Essentials as well as the MooTools online tutorial. I work at a company in the SF Bay Area called Cloudera. I can be contacted thusly. -

      - - -
      -

      A note on comments here: These comments are moderated. No comments will show up until they are approved. Comments that are not productive (i.e. inflammatory, rude, etc) will not be approved. Similarly, "fan" comments won't be approved either - i.e. no "FrameworkX Rulez! It's better than FrameworkY for realz!" are not constructive comments. -

      -
      - - -
      - - - - - - +

      + Now we have a version of our FAQ class that allows us to get the definitions from the server. Note that we were able to integrate the new logic in a way that doesn't expand the definition until after the content comes back from the server (which we couldn't do with the jQuery version). Also note that we really only had to describe the new functionality (the ajax) and little else. This extensibility makes it possible for you to create families of plug-ins that offer different shades of functionality. It also means that you can use someone else's plug-in and alter just the bits that you to be want different if you need to (without forking it). This helps explain why, for any given design pattern - a date picker, a tab interface, etc, that you typically only find a few plug-ins for MooTools. Most of the plug-ins you get either solve your problem or, if not, you can just extend them to add the things you need. + +

      + +

      + As I illustrated earlier, it's possible to write complex jQuery widgets with methods and state. Most of the code you write when doing this is vanilla JavaScript when you need to express logic that isn't related to the DOM. But jQuery's model doesn't offer a system for extending these instances into subclasses. Nor does it help you with mixins that can be reused easily. Finally, jQuery's plugins are always attached to DOM elements. If you wanted to write a class that, say, processed URLs, there's no stateful system for such a thing unless you write it yourself. +

      + + +

      Decision Time

      + +

      + jQuery focuses on expressiveness, quick and easy coding, and the DOM while MooTools focuses on extension, inheritance, legibility, reuse, and maintainability. If you put those two things on opposite sides of a scale, the jQuery side translates into something with which it's easy to get started and see quick results but (in my experience) can turn into code that's harder to reuse and maintain (but really that's up to you; it's not jQuery's problem, per se), while the MooTools side takes longer to learn and requires you to write more code upfront before you see results, but afterwards is more reusable and more maintainable. +

      +

      + Further, the MooTools core does not contain every feature you can imagine and neither does the jQuery core. Both frameworks keep their cores rather lean, leaving it to you and others to write plug-ins and extensions. Their job is not to give you every feature you could want but to give you the tools so that you can implement anything you can imagine. This is the power of JavaScript, and of JavaScript frameworks in general, and both frameworks excel at it. MooTools takes a more holistic approach and gives you tools to write anything you can imagine beyond the scope of the DOM, but pays the price by having a steeper learning curve. MooTools' extensible and holistic approach gives you a superset of jQuery's features, but jQuery's focus on a slick DOM API doesn't preclude you from using the native inheritance methods of JavaScript or from using a class system like MooTools if you want it. +

      +

      + This is why I say that both frameworks are excellent choices. My effort here has been to highlight the differences in philosophies between the two codebases and highlight their advantages and disadvantages. I doubt I've been successful in keeping my preference for MooTools completely in check, but hopefully this has been helpful. Regardless of which framework you choose to work with, you now know a lot more about both, hopefully. If you have the luxury of time, I strongly recommend implementing a site with each. Then write your own review of them both and maybe your perspective will highlight some things I missed. +

      +

      A history of this document can be viewed on github.

      +

      + +

      +
      +

      + About me: I am a MooTools contributor and I blog about JavaScript and other things on my site Clientcide as well as release numerous plug-ins for MooTools. I am the author of MooTools Essentials as well as the MooTools online tutorial. I work at a company in the SF Bay Area called Cloudera. I can be contacted thusly. +

      + + +
      +

      A note on comments here: These comments are moderated. No comments will show up until they are approved. Comments that are not productive (i.e. inflammatory, rude, etc) will not be approved. Similarly, "fan" comments won't be approved either - i.e. no "FrameworkX Rulez! It's better than FrameworkY for realz!" are not constructive comments. +

      +
      + + +
      + + + + + + \ No newline at end of file From 534f782798497a031016016e5a6d92060940e93f Mon Sep 17 00:00:00 2001 From: Ivan Ivanov Date: Mon, 20 Aug 2012 15:53:23 +0400 Subject: [PATCH 5/8] And yet --- index_ru.html | 66 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 47 insertions(+), 19 deletions(-) diff --git a/index_ru.html b/index_ru.html index 43dd2d3..2b80d5e 100644 --- a/index_ru.html +++ b/index_ru.html @@ -479,7 +479,7 @@

      MooTools делает Javascript более крутым

      Element и других прототипов. Также, очень важная часть — функция Class.

      - Class для многих людей выглядит так, как будто мы попытались воссоздать более классическое + Class для многих людей выглядит как попытка воссоздать более классическое наследование, как в Java или C++, но это не так. Основная задача Class — сделать модель прототипного наследования более простой @@ -492,17 +492,19 @@

      MooTools делает Javascript более крутым

      -

      jQuery Makes the DOM More Fun

      - +

      jQuery делает DOM более крутым

      - And this is why jQuery is more accessible. It doesn't ask that you learn JavaScript inside and out. It doesn't throw you into the deep end with prototypal inheritance, binding, "this", and native prototypes. When you get started with jQuery in its official tutorial, this is the first jQuery code example you find: + И поэтому jQuery более доступен. Он не заставляет вас учить JavaScript с головы до пят. + Он не кидает вас в дебри прототипного наследования, связываний, "this" и тому подобного. + Когда вы начинаете изучать jQuery с его официального руководства, + вот первый пример кода, который вы увидите:

      window.onload = function() {
           alert("welcome");
       }
      -

      and here's the third:

      +

      а вот третий:

      $(document).ready(function() {
           $("a").click(function(event) {
      @@ -511,21 +513,36 @@ 

      jQuery Makes the DOM More Fun

      });

      - If you read the MooTools book or the MooTools tutorial (both of which I authored) they start in a much different place. While you can skip ahead and quickly learn about effects and the DOM, if you want to learn MooTools, you have to start with things like Class, and, I'll admit: if you're new to programming, or you just want to get something working on your site without having to learn everything about JavaScript, chances are jQuery is going to look a lot more friendly to you. + Если вы читали + the MooTools book + или MooTools tutorial (и то, и другое написал я), + они начинаются совсем с других вещей. + Вы могли бы пропустить основы и начать читать об эффектах на странице и о DOM, но если вы хотите + изучить MooTools, придется начать с вещей типа Class, и я признаю: + если вы новичок в программировании, или просто хотите, чтобы на вашем сайте что-то быстро + заработало, а вам бы не пришлось изучать JavaScript, скорей всего, jQuery вам понравится гораздо больше.

      -

      - On the other hand, if you want to learn JavaScript itself, MooTools is a great way to do it. It implements a lot of things that JavaScript is going to have (many of the methods on Natives are just the JavaScript 1.8 spec and beyond). If you're used to programming, especially both object oriented and functional programming, MooTools has a lot of design patterns that are very exciting and expressive. + С другой стороны, если вы хотите изучить сам JavaScript, MooTools — отличный способ это сделать. + Если вы привыкли программировать, особенно в функциональном и объектно-ориентированном стилях, + у MooTools есть много чего вам предложить.

      -

      Anything You Can Do I Can Do Better

      - +

      Все, что можете вы, я могу сделать лучше

      - If you look at the things jQuery can do, there's often a counterpart in MooTools. If you look at the things MooTools can do, there is often no way to emulate it using jQuery code because of jQuery's focus on the DOM. MooTools has a broader functionality than jQuery, but there's nothing about jQuery that prevents you from doing those things. For example, jQuery does not come with any sort of inheritance system, but that's ok. You could, if you want, use the MooTools Class in conjunction with jQuery if you wanted to (or write your own). There's even an inheritance plug-in for jQuery (I haven't used it, but I assume it offers pretty much the same kind of functionality). + Если вы взглянете на вещи, которые может делать jQuery, вы увидите, что + часто у них есть аналог в MooTools. Если вы взглянете на вещи, которые может делать MooTools, + часто не найдется способа повторить их с помощью jQuery, поскольку jQuery сфокусирован только на DOM. + MooTools обладает более широкой функциональностью нежели jQuery, но в этом нет ничего плохого. + Например, jQuery не предлагает никакой системы наследования, ну и хорошо. Вы можете использовать Class + из MooTools вместе с jQuery, если хотите (или написать свою). Есть даже + плагин для наследования в jQuery + (Я его не использовал, но предполагаю, что он предоставляет весьма схожую функциональность). +

      +

      + Если мы посмотрим на пример из jQuery выше:

      - -

      If we look at the example from jQuery above:

      $(document).ready(function() {
           $("a").click(function(event) {
      @@ -534,7 +551,7 @@ 

      Anything You Can Do I Can Do Better

      });

      - and we wanted to translate this to MooTools, we'd have: + и захотим перевести это на MooTools, то получится:

      window.addEvent('domready', function() {
           $$('a').addEvent('click', function(event) {
      @@ -542,10 +559,10 @@ 

      Anything You Can Do I Can Do Better

      }); });

      - These are very similar no? + Довольно похоже, нет?

      - Here's a more complex example from jQuery: + Вот более сложный пример из jQuery:

      $(document).ready(function() {
      @@ -558,7 +575,7 @@ 

      Anything You Can Do I Can Do Better

      });

      - and in MooTools: + и из MooTools:

      window.addEvent('domready',function() {
      @@ -573,11 +590,22 @@ 

      Anything You Can Do I Can Do Better

      });

      - Again, very similar. I'd argue that the MooTools version is more explicit, but also more verbose because of it. It's clear reading the MooTools code that we're adding two events - one for mouse enter and one on mouse leave, while the jQuery version is more concise; its hover method accepts two methods - the first for mouse enter and the second for mouse leave. I personally like the fact that the MooTools code is more legible but that's a very subjective observation. + И снова очень похоже. Я бы сказал, что версия MooTools более явная, но поэтому и писать приходится чуть больше. + Глядя на код для MooTools, понятно что мы добавляем два события — одно для mouseenter и одно для mouseleave, + в то время как версия для jQuery более краткая. Его метод hover + принимает две функции — первую для mouseenter и вторую для mouseleave. + Лично мне нравится, что код для MooTools более разборчивый, но это мое субъективное наблюдение.

      - I will say that sometimes jQuery can become too esoteric for my taste. The methods don't always make sense to me just looking at them and I find it hard to parse. This is somewhat unfair though, as I am intimately familiar with MooTools, so reading MooTools is easy for me. But one of the things I appreciate about MooTools is how almost all the method and class names really name the thing. Methods are almost always verbs and leave little doubt as to what they do. Every programming language requires you to go to the docs to look up syntax when you write it - I'm not saying that. I'm just saying that I find the API of MooTools to be more coherent and consistent. + Я бы сказал, иногда jQuery может быть слишком эзотерическим, на мой вкус. Например, мне не очевидно, + что делают методы из примера выше, если просто на них посмотреть, и поэтому этот код сложнее прочитать. + Хотя, это может быть несправедливо, так как я глубоко знаю MooTools, поэтому читать код MooTools для меня + легче. Но есть одна вещь, которую я очень ценю в MooTools — это то, что почти все методы и + названия классов обозначают именно то, как и называются. Методы почти всегда — глаголы, и практически + всегда по названию понятно, что они делают. Любой язык программирования требует время от времени пойти + и заглянуть в документацию, чтобы посмотреть синтаксис, и я не говорю, что в MooTools этого делать не надо, + я просто говорю, что нахожу API MooTools более понятным и последовательным.

      From ceb735466e118660536a7e9055a833fe8d90ec40 Mon Sep 17 00:00:00 2001 From: Ivan Ivanov Date: Wed, 22 Aug 2012 15:02:05 +0400 Subject: [PATCH 6/8] Yet --- index_ru.html | 301 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 242 insertions(+), 59 deletions(-) diff --git a/index_ru.html b/index_ru.html index 2b80d5e..6b435d2 100644 --- a/index_ru.html +++ b/index_ru.html @@ -609,9 +609,12 @@

      Все, что можете вы, я могу сделать лучше

      -

      MooTools Lets You Have It Your Way

      - -

      But what if you like the jQuery syntax? One way to illustrate the power of MooTools is to show you how easy it is to change it to suit your tastes. If we wanted to implement the hover method from jQuery in MooTools, we could easily do so:

      +

      Настройте MooTools, как это нужно вам

      +

      + Но что если вам нравится синтаксис jQuery? Не проблема, я покажу, как просто можно изменить синтаксис + MooTools на любой вкус. Если бы, например, мы хотели создать метод hover, как в jQuery, мы могли бы + просто сделать так: +

      Element.implement({
           hover : function(enter,leave){
      @@ -619,7 +622,7 @@ 

      MooTools Lets You Have It Your Way

      } }); -//and then you could use it exactly like the jQuery version: +// и теперь используем его точно так же, как в jQuery $$('#orderlist li:last').hover(function(){ this.addClass('green'); }, @@ -628,13 +631,18 @@

      MooTools Lets You Have It Your Way

      });
      -

      Indeed, there are MooTools plug-ins that do just that; give you the jQuery syntax for MooTools. MooTools' focus on extensibility means you can implement anything you like. This is something jQuery can't do. MooTools can mimic jQuery if you want it to, but jQuery can't mimic MooTools. If you want to write classes or extend native prototypes or do some of the other things MooTools can, you'll have to write it yourself.

      +

      + В самом деле, для MooTools есть плагины, которые делают именно это. + То, что MooTools фокусируется на расширяемости, означает, что вы можете реализовать все, что захотите. + Это то, что jQuery не умеет. MooTools может маскироваться под jQuery, а jQuery под MooTools — нет. + Если вы захотите писать классы, или расширять существующие прототипы, или делать другие вещи, которые + умеет MooTools, вам придется писать это самим. +

      -

      Chaining as a Design Pattern

      - +

      Chaining как паттерн проектирования

      - Let's do another of these. Here's some jQuery (from the jQuery tutorial): + Давайте взглянем на кое-что еще. Вот немного jQuery (из официального руководства):

      $(document).ready(function() {
      @@ -644,10 +652,16 @@ 

      Chaining as a Design Pattern

      });

      - This is an example of a syntax that I personally don't prefer. Looking at the code above I am hard pressed to be sure of what it's doing. Most notably I'm curious about what .end does and how does .find, which follows it, relate to what .end does? Now, looking at the docs on jQuery makes it very clear what .end does (it resets to the value of the original selector, in this case #faq). But this seems very odd to me. When I do work with jQuery, I often find myself unsure what a method is going to return to me. Obviously this doesn't bother everyone else as jQuery has a lot of people happily using it, so I'll chalk it up to personal preference again. + Это пример синтаксиса, который лично я не очень люблю. Глядя на кусок кода вверху, я с трудом смогу + сказать, что он делает. Особенно интересно, что делает .end и как .find, который идет + за ним, относится к тому, что делает .end? Поглядев в документацию jQuery, становится понятно, + что делает .end (он сбрасывает до значения самого первого селектора, в данном случае #faq). + Но для меня это выглядит очень странно. Когда я работаю с jQuery, я часто обнаруживаю, что не уверен, + что какой-либо метод собирается мне вернуть. Очевидно, это не беспокоит больше никого, так как + многие люди используют jQuery и вполне счастливы, так что припишу это опять своим личным предпочтениям.

      - Let's look at the above logic as MooTools: + Давайте посмотрим, как это выглядело бы в MooTools:

      window.addEvent('domready', function() {
      @@ -659,9 +673,11 @@ 

      Chaining as a Design Pattern

      });
      -

      - Again, the MooTools code is a bit more verbose, but also more explicit. Also note that the design pattern here is to store the reference to #faq in a variable, where jQuery uses its .end method to return to it. I'll note that it's possible to write highly chained code with Mootools. For example: + И снова, кода для MooTools слегка побольше, но он зато и более явный. Также заметьте, что + подход здесь заключается в хранении ссылки на #faq в переменной, тогда как jQuery + использует специальный метод .end, чтобы вернуться к нему. В MooTools тоже возможно + написать код в одну цепочку, например:

      item.getElements('input[type=checkbox]')
           .filter(function(box) {
      @@ -672,17 +688,26 @@ 

      Chaining as a Design Pattern

      .fireEvent((checked) ? 'check' : 'uncheck');

      - But really, writing code like this - lots of logic in a domready statement - with either framework, I'd argue, is itself a bad practice. It's far better to encapsulate your logic into reusable chunks. + Но, в самом деле, писать код вроде этого — куча логики в выражении domready — в любом + фреймворке, само по себе не очень хорошо. Гораздо лучше разбить вашу логику на куски, пригодные для + повторного использования.

      -

      Reusing Code with jQuery

      - +

      Повторное использование кода в jQuery

      - It's very tempting when you're working on a web project to write code this way. Just add some logic on the page that selects the DOM elements and "sets them up" by hiding some, altering others, and adding event listeners for click or mouseover. Developing code this way is very efficient, very fast. The problem with writing all your logic in domready statements is that you end up with a lot of code that does the same thing in different places. If we take the FAQ pattern above we could easily apply the same logic elsewhere on a different page with any list of terms and definitions. Are we going to repeat the same logic every time we find this pattern? + Когда вы работаете над веб-проектом, писать код таким образом очень заманчиво. Просто добавить на страницу + немного кода, который выбирает элементы из DOM, и "обрабатывает их", скрывая одни, изменяя другие и + добавляя обработчики событий click и mouseover. Писать код таким образом очень эффективно и очень быстро. + Однако, проблема в написании всей логики в выражении domready в том, что у вас в итоге окажется + множество кода в разных местах, делающее одно и то же. Если взять код про FAQ из примера выше, + мы можем легко поместить такую же логику в другое место, на другую страницу, с любым списком + заголовков и определений. Надо ли нам повторять ту же самую логику каждый раз, когда мы сталкиваемся с + подобной задачей?

      - A simple way to make it reusable is to wrap the logic in a function and pass in arguments. Here's what that might look like in jQuery: + Простой способ написать реюзабельный код — это обернуть его в функцию и передать ей аргументы. + Вот как это может выглядеть на jQuery:

      function faq(container, terms, definitions) {
      @@ -695,25 +720,39 @@ 

      Reusing Code with jQuery

      });

      - This is much better for two really big and important reasons: + Это гораздо лучше по двум большим и важным причинам:

      1. - If tomorrow we need to change how these lists work (maybe we want to add click tracking logic so we can measure it in our web logs or maybe we want to fetch the definitions via ajax) we can just change our main faq method and everywhere we use it just gets updated. Or if there's a new version of jQuery released that changes the way things work, we can just go update our one method instead of a dozen copies everywhere. I call this keeping a small footprint in my application. By keeping the points where my application touches my more generic code as small as possible, it makes it easier for me to fix bugs, upgrade frameworks, add features, or alter functionality. + Если завтра мы захотим изменить то, как эти списки работают (например, добавить трекинг кликов, чтобы + можно было потом их отслеживать в логах; или, например, получать куски кода через ajax), нам нужно + будет изменить только главный метод faq, и везде, где он был использован, все будет работать + нормально. Или если вдруг обновится версия jQuery, в которой были сделаны изменения, требующие + изменить код, нам придется изменить один метод, а не десять в разных местах. Я называю это + "стараться оставлять маленькие следы" (keeping a small footprint). Если стараться держать код, + где приложение затрагивает более общий код, насколько маленьким, насколько возможно, становится + гораздо проще исправлять ошибки, обновлять фреймворки, добавлять фичи или изменять функциональность.
      2. - The second reason is that it's less code. By reusing the same method over and over again, I don't repeat myself and this is valuable in any programming environment. It also makes the code my visitors have to download smaller. + Вторая причина — меньше кода. Используя один и тот же метод несколько раз, мы не плодим + дубликаты, а это важно при программировании чего угодно. Ну, и посетителям сайта приходится скачивать + меньше кода.

      - jQuery actually has a slightly more refined system for writing reusable "widgets" like these. Rather than encourage you to drop them into functions like the above example (which is really rather crude) it encourages you to write jQuery plug-ins. Here's what that would look like: + На самом деле, у jQuery есть немного более проработанная система для написания "виджетов" вроде этих, + пригодных для повторного использования. Вместо того, чтобы поощрять вас разбивать код на функции, + как в предыдущем примере (что и правда довольно грубо), он побуждает вас писать + jQuery плагины. + Вот как это примерно может выглядеть:

      jQuery.fn.faq = function(options) {
           var settings = jQuery.extend({
               terms: 'dt',
               definitions: 'dd'
           }, options); 
      -    //"this" is the current context; in this case, the elements we want to turn into faq layouts
      +    // "this" - это текущий контекст,
      +    // в данном случае - элементы, которые мы хотим превратить в разделы FAQ
           $(this).find(settings.terms).hide().end().find(settings.definitions).click(function() {
               $(this).next().slideToggle();
           });
      @@ -721,27 +760,55 @@ 

      Reusing Code with jQuery

      };

      - which you would use thusly: + а использовать это вы будете таким образом:

      $('#faq').faq();

      - But looking at the example above, there's not much difference between declaring our faq function this way vs. declaring it as a stand alone function. Granted, it's not in the global namespace, but we could have just as easily added it to a namespace of our own. By attaching it to jQuery we can chain it with other jquery methods. The other benefit is that the "this" inside our function is the current context of whatever is in the jQuery chain at that moment. By using this pattern for plug-ins we're able to make our plug-in look like it's part of jQuery, but other than that, our plug-in is basically a single function that takes the current jQuery context, does stuff to it, and then returns the context for the next item in the chain. There's not a lot of complexity here, which makes it easy for anyone to write jQuery plug-ins - they're just single functions. + Но, глядя на пример выше, видно, что нет большой разницы между объявлением нашей функции faq + таким образом и объявлением ее как обычной функции. Конечно, тогда она не мусорит в глобальном неймспейсе, + но мы могли бы и руками добавить ее в свой неймспейс, что ничуть не сложнее. Присоединив + ее к jQuery, мы получаем возможность добавлять ее в цепочки с другими методами. Другое преимущество + в том, что "this" внутри нашей функции тогда будет являться текущим контекстом всего, что будет + в цепочке к тому моменту. Поэтому, если создавать плагины таким образом, они выглядят совсем как часть + jQuery, но, вообще говоря, наш плагин по существу — обычная + функция, которая принимает текущий контекст, делает с ним разные штуки и затем возвращает, чтобы + следующая функция в цепочке могла им воспользоваться. Ничего особенно сложного в этом нет, поэтому + писать плагины для jQuery довольно легко, т.к. они всего лишь обычные функции.

      - Note that it is possible to write more complex plugins with jQuery with methods and state. This kind of pattern is supported with the jQuery UI plugin system and doesn't use the same mechanism as the basic plugin (like our faq example). Instead, you attach an object with methods and properties to the jQuery object (i.e. $.ui.tabs). There's a shortcut to invoke this object ($(selector).tabs()) so that you can continue chaining as with the faq plugin. But because it doesn't return a reference to the tabs object created for the items in your selector, you're forced to call that selector again to invoke methods on it. Instead of calling myTabInstance.add(url, label, index) you must execute the selector again and call your function by name (as a string): $(selector).tabs('add', url, label, index);. This means you're running your selector twice (unless you store it in a variable somewhere), and that you don't ever have a pointer to the "add" method that you can do things like bind or delay. This post is focused on the MooTools and jQuery cores, and while jQuery's UI system does provide this functionality, it's not something that comes with jQuery by default. + Заметьте, что в jQuery можно писать более сложные плагины, с методами и хранением состояния. + Это позволяет сделать система плагинов jQuery UI, которая не использует тот механизм, который я + описал выше, в примере с faq. Вместо этого, вы привязываете свой объект к объекту jQuery + (например, $.ui.tabs) и можете потом использовать его в коде примерно как $(selector).tabs(), + чтобы можно было продолжать строить цепочку, как в примерах выше. Однако, поскольку это выражение не + возвращает ссылку на объект, который мы создали для наших табов внутри селектора, вам придется + снова выполнять поиск по селектору, чтобы вызывать его методы. И вместо того, чтобы просто вызвать + myTabInstance.add(url, label, index), вам придется вызывать функции, передавая их имена + строками, например $(selector).tabs('add', url, label, index);. Таким образом, вы + выполняете поиск по селектору дважды, если, конечно, не сохранили результат в переменную, и не имеете + под рукой ссылку на функцию add, чтобы можно было использовать штуки вроде bind или delay. Но поскольку этот + пост про ядро jQuery и ядро MooTools, надо сказать, что данная функциональность предоставляется + jQuery UI и в ядро по умолчанию не входит.

      -

      Reusing Code with MooTools

      - +

      Повторное использование кода в MooTools

      - In MooTools when you want to define a pattern, you're more likely to use either a Class or implement a method into a native object (into String, for example). -

      + In MooTools when you want to define a pattern, you're more likely to use either a + Class or implement a method into a + native object (into String, for example). +

      - Rather than give you an almost completely different language from JavaScript's native style, MooTools attempts to walk the middle ground between defining its own custom syntax and extending JavaScript's own design patterns. One of the ways it does this is by extending the prototypes of the native objects in the language and in the DOM. This means that if you needed a method to trim a string, MooTools encourages you to add that method to String itself (note that String.trim is already in MooTools; you don't need to add this yourself): + Rather than give you an almost completely different language from JavaScript's native style, + MooTools attempts to walk the middle ground between defining its own custom syntax and extending + JavaScript's own design patterns. One of the ways it does this is by extending the prototypes of the + native objects in the language and in the DOM. This means that if you needed a method to trim a string, + MooTools encourages you to add that method to String itself + (note that String.trim is + already in MooTools; you don't need to add this yourself):

      String.implement({
      @@ -751,13 +818,32 @@ 

      Reusing Code with MooTools

      });

      - This means you can just execute " no more spaces on the end! ".trim() and get back "no more spaces on the end!". Some would say that implementing properties into native prototypes is inappropriate. It's the reason why MooTools and Prototype.js can't play well with each other - any framework that manipulates prototypes of natives doesn't play well with any other framework that does the same. If I define String.prototype.foo() and another library on the same page defines it, too, which ever one comes last wins. In a way, this is similar to the problem we face with the global window namespace. This is how JavaScript works. This is how JavaScript 1.8 has added so many features. It adds them to the prototypes. + This means you can just execute " no more spaces on the end! ".trim() and get back "no more + spaces on the end!". Some would say that implementing properties into native prototypes is + inappropriate. It's the reason why MooTools and Prototype.js + can't play well with each other - any framework that manipulates prototypes of natives doesn't play + well with any other framework that does the same. If I define String.prototype.foo() and another + library on the same page defines it, too, which ever one comes last wins. In a way, this is similar to + the problem we face with the global window namespace. This is how JavaScript works. This is how + JavaScript 1.8 has added so many + features. It adds them to the prototypes.

      - The MooTools developers include a robust framework that is easy for you to extend with your own functionality with the intention that people who include the framework in the page are going to use it, not some other framework. It's actually kind of rude to ask users to download two frameworks. The only reason to include two frameworks is because you want to use plug-ins from both, and in the minds of the MooTools authors (myself included), if you want a plug-in that isn't available with the framework of your choice, it's more appropriate for you to spend the time porting it to your environment than to ask your users to download another framework. + The MooTools developers include a robust framework that is easy for you to extend with your own + functionality with the intention that people who include the framework in the page are going to use + it, not some other framework. It's actually kind of rude to ask users to download two frameworks. + The only reason to include two frameworks is because you want to use plug-ins from both, and in the + minds of the MooTools authors (myself included), if you want a plug-in that isn't available with the + framework of your choice, it's more appropriate for you to spend the time porting it to your + environment than to ask your users to download another framework.

      - Once you learn how JavaScript works and see the power of extending native objects, a whole new level of programming opens up. You can write plug-ins that alter Elements or Dates or Functions. While some might argue that adding methods to natives this way is a kind of pollution, I'd argue that this is how JavaScript is meant to be used. It is a design feature of the language. By attaching methods to natives you allow your code to be concise and compartmentalized. jQuery does this too, but limits its prototype enhancements to the jQuery object. + Once you learn how JavaScript works and see the power of extending native objects, a whole new level + of programming opens up. You can write plug-ins that alter Elements or Dates or Functions. While some + might argue that adding methods to natives this way is a kind of pollution, I'd argue that this is how + JavaScript is meant to be used. It is a design feature of the language. By attaching methods to natives + you allow your code to be concise and compartmentalized. jQuery does this too, but limits its prototype + enhancements to the jQuery object.

      @@ -779,7 +865,12 @@

      Reusing Code with MooTools

      - The key here is that at the heart of the MooTools framework is the notion that it's there to let you program what you want. If there's functionality that's not in the core, you can extend it and add your own. The job of the core is not to provide everyone with every bit of functionality that they could ever want, but to provide the tools that allow you write the things that you want. A big part of that is making it easier to extend the prototypes of natives, and take advantage of prototypal inheritance. You can do these things with vanilla JavaScript but MooTools makes it easier and more pleasant. + The key here is that at the heart of the MooTools framework is the notion that it's there to let you + program what you want. If there's functionality that's not in the core, you can extend it and add your + own. The job of the core is not to provide everyone with every bit of functionality that they could + ever want, but to provide the tools that allow you write the things that you want. A big part of that + is making it easier to extend the prototypes of natives, and take advantage of prototypal inheritance. + You can do these things with vanilla JavaScript but MooTools makes it easier and more pleasant.

      @@ -788,7 +879,12 @@

      Reusing Code with MooTools

      MooTools and Inheritance

      - Despite its name, the MooTools Class function is not really a class nor does it create them. It has design patterns that might remind you of classes in a more traditional programming language, but really Class is all about objects and prototypal inheritance. (Unfortunately, using words like "class" are the most convenient way to describe these things, so for the purposes of this article, when I refer to "classes" I'm referring to functions that return objects - which I'll call "instances" - that inherit from a prototype.) + Despite its name, the MooTools Class function is not really a class nor does it create them. + It has design patterns that might remind you of classes in a more traditional programming language, + but really Class is all about objects and prototypal inheritance. (Unfortunately, using words + like "class" are the most convenient way to describe these things, so for the purposes of this article, + when I refer to "classes" I'm referring to functions that return objects - which I'll call "instances" + - that inherit from a prototype.)

      To make a class, you pass an object to the Class constructor like this: @@ -807,18 +903,33 @@

      MooTools and Inheritance

      });

      - You pass Class an object (above, we pass an object with members like "isAlive" and "eat") and this object becomes the prototype of every instance of that class. To create an instance, you call it like this: + You pass Class an object (above, we pass an object with members like "isAlive" and "eat") and + this object becomes the prototype of every instance of that class. To create an instance, you call it + like this:

      var bob = new Human("bob", 20); //bob's name is "bob" and he's 20 years old.

      - Now we have an instance of Human. bob has the properties of the object we defined when we created our Human class. But the important thing is that bob has these properties through inheritance. When we reference bob.eat, bob doesn't really have this property. JavaScript looks at bob and he doesn't have an eat method, so it looks up the inheritance chain and finds it on the object we passed when we created the Human class. This is true for energy, too. At first glance this looks potentially bad; we don't want all the humans we create to gain energy every time that bob eats. The important thing to recognize is that the first time we assign a value to bob's energy, we assign him his own value and we no longer look at the prototype for it. So the first time bob eats, he gets his own definition for energy (set to 2). + Now we have an instance of Human. bob has the properties of the object we defined + when we created our Human class. But the important thing is that bob has these + properties through inheritance. When we reference bob.eat, bob doesn't really have + this property. JavaScript looks at bob and he doesn't have an eat method, so it looks + up the inheritance chain and finds it on the object we passed when we created the Human class. + This is true for energy, too. At first glance this looks potentially bad; we don't want all the + humans we create to gain energy every time that bob eats. The important thing to recognize is + that the first time we assign a value to bob's energy, we assign him his own value and we no + longer look at the prototype for it. So the first time bob eats, he gets his own definition for + energy (set to 2).

      bob.eat(); //bob.energy == 2

      - Note that bob's name and age are unique to him; these are assigned to him when the class is initialized in the initialize method. + Note that bob's name and age are unique to him; these are assigned to him when the class is + initialized in the initialize method.

      - This whole pattern may seem a little odd to you, but the value here is that we can define functionality for a pattern and create instances of that pattern every time we need it. Each instance maintains its own state. So if we create another instance each one is independent of the other, but inherits from the same base pattern: + This whole pattern may seem a little odd to you, but the value here is that we can define functionality + for a pattern and create instances of that pattern every time we need it. Each instance maintains its + own state. So if we create another instance each one is independent of the other, but inherits from + the same base pattern:

      var Alice = new Human();
      @@ -833,10 +944,15 @@ 

      MooTools and Inheritance

      Extending and Implementing Classes

      - Let's revisit our jQuery faq plug-in. What would happen if we wanted to add more functionality to that plug-in. What if we wanted to make an ajax version that fetched the answers to the questions from the server? Let's imagine that the faq plug-in was authored by someone else and we want to add more to it without altering it in any way (we don't want to fork it). + Let's revisit our jQuery faq plug-in. What would happen if we wanted to add more functionality + to that plug-in. What if we wanted to make an ajax version that fetched the answers to the questions + from the server? Let's imagine that the faq plug-in was authored by someone else and we want to + add more to it without altering it in any way (we don't want to fork it).

      - Our only real choices are to either duplicate the faq plug-in's logic entirely (remember, it's a single function), essentially forking it, or we can invoke it and then add more logic to it. Given a choice, the latter seems to save us the most trouble. It would look something like this: + Our only real choices are to either duplicate the faq plug-in's logic entirely (remember, + it's a single function), essentially forking it, or we can invoke it and then add more logic to it. + Given a choice, the latter seems to save us the most trouble. It would look something like this:

      jQuery.fn.ajaxFaq = function(options) {
           var settings = jQuery.extend({ 
      @@ -851,10 +967,18 @@ 

      Extending and Implementing Classes

      this.faq(); //call our original faq plug-in });

      - This has some down sides. First of all, our faq class is going to repeat our selector for the definitions, which might be expensive; there's no way to store the retrieved definitions and pass it on for the second time they are needed. Secondly, we can't add our ajax logic into the middle of the faq plug-in's own logic for displaying the definition. The original plug-in called slideToggle which expands the definition using an effect. This is problematic because this effect is going to go off before our ajax finishes loading. There's no real solution here unless we just duplicate the entire faq plug-in. + This has some down sides. First of all, our faq class is going to repeat our selector for + the definitions, which might be expensive; there's no way to store the retrieved definitions and + pass it on for the second time they are needed. Secondly, we can't add our ajax logic into the middle + of the faq plug-in's own logic for displaying the definition. The original plug-in called + slideToggle which expands the definition using an effect. This is problematic because this + effect is going to go off before our ajax finishes loading. There's no real solution here unless we + just duplicate the entire faq plug-in.

      - Now let's consider our MooTools Human class. It has properties like isAlive and energy and it has a method called eat. What if we wanted to make a new version of Human that had additional properties? With MooTools, we extend the class: + Now let's consider our MooTools Human class. It has properties like isAlive and + energy and it has a method called eat. What if we wanted to make a new version of + Human that had additional properties? With MooTools, we extend the class:

      var Ninja = new Class({
           Extends: Human,
      @@ -869,7 +993,10 @@ 

      Extending and Implementing Classes

      } });

      - You can see that we've added a lot of functionality here into a subclass. This subclass has all these properties that are unique to Ninjas. Ninjas start off with an initial energy value of 100. Ninjas get a side. They also get an attack method that lets them kill other Humans, but it costs the Ninja energy. + You can see that we've added a lot of functionality here into a subclass. This subclass has all these + properties that are unique to Ninjas. Ninjas start off with an initial energy + value of 100. Ninjas get a side. They also get an attack method that lets + them kill other Humans, but it costs the Ninja energy.

      var bob = new Human('Bob', 25);
      @@ -880,7 +1007,14 @@ 

      Extending and Implementing Classes

      //bob never had a chance

      - Picking this apart a bit, there are some interesting things to consider here. Note that we have an initialize method in the Ninja class. This would appear to overwrite the initialize method in the Human class, but we can still access it by calling this.parent, passing along the arguments that the parent class's initialize expects. Further, we can control when our logic occurs; before or after the call to the parent. We can assign new values to properties (like the energy value) and we can define new functionality. Imagine if we could do this with our faq plug-in for jQuery. We could load our ajax and THEN slide open the value. + Picking this apart a bit, there are some interesting things to consider here. Note that we have an + initialize method in the Ninja class. This would appear to overwrite the + initialize method in the Human class, but we can still access it by calling + this.parent, passing along the arguments that the parent class's initialize expects. + Further, we can control when our logic occurs; before or after the call to the parent. We can assign + new values to properties (like the energy value) and we can define new functionality. + Imagine if we could do this with our faq plug-in for jQuery. We could load our ajax and THEN + slide open the value.

      MooTools has another pattern called a Mixin. Unlike the parent to @@ -900,7 +1034,9 @@

      Extending and Implementing Classes

      });

      - Here we've broken the qualities that make a Ninja different from a Human and put them in a class of their own. This lets us reuse this code outside of Ninja. We could then imbue our Ninja class with the qualities of a warrior like so: + Here we've broken the qualities that make a Ninja different from a Human and put + them in a class of their own. This lets us reuse this code outside of Ninja. We could then + imbue our Ninja class with the qualities of a warrior like so:

      var Ninja = new Class({
      @@ -923,11 +1059,19 @@ 

      Extending and Implementing Classes

      });

      - Now we have a Samurai class and a Ninja class. But look at how little code both Ninja and Samurai took to define. Both of them are similar in that they are humans with warrior qualities, but they are different in that samurais are always, always good, while ninjas have shifting allegiances. By spending the time to write a Human class and a Warrior class, we're able to have three different classes with no repetition of code while maintaining a very granular level of control over when methods are called and how they relate to each other. Each instance we create has its own state and the code itself is very legible. + Now we have a Samurai class and a Ninja class. But look at how little code both + Ninja and Samurai took to define. Both of them are similar in that they are humans + with warrior qualities, but they are different in that samurais are always, always good, while ninjas + have shifting allegiances. By spending the time to write a Human class and a Warrior + class, we're able to have three different classes with no repetition of code while maintaining a very + granular level of control over when methods are called and how they relate to each other. Each instance + we create has its own state and the code itself is very legible.

      - Now that you have an overview of how classes work in MooTools, let's look at our faq class that we wrote in jQuery and write it as we would in MooTools and then extend it to add Ajax to it just as we did with jQuery. + Now that you have an overview of how classes work in MooTools, let's look at our faq + class that we wrote in jQuery and write it as we would in MooTools and then extend it to add Ajax + to it just as we did with jQuery.

       var FAQ = new Class({
      @@ -971,7 +1115,10 @@ 

      Extending and Implementing Classes

      - Woah. That's a lot of code. Even if we remove all the comments it's still two dozen lines long. I already illustrated above that we could build this plug-in with roughly the same amount of code as the jQuery version. So why is this one so much longer? Well, we've made it much more flexible. To use the class, we just call the constructor, like this: + Woah. That's a lot of code. Even if we remove all the comments it's still two dozen lines long. + I already illustrated above that we could build this plug-in with roughly the same amount of code + as the jQuery version. So why is this one so much longer? Well, we've made it much more flexible. + To use the class, we just call the constructor, like this:

      var myFAQ = new FAQ(myContainer);
      @@ -980,7 +1127,9 @@ 

      Extending and Implementing Classes

      - We can access methods and properties of the instance. But what about our ajax functionality? The problem with our ajax extension to the jQuery version was that we couldn't delay the opening of the definition until after it loaded. We don't have that problem with our MooTools version: + We can access methods and properties of the instance. But what about our ajax functionality? The + problem with our ajax extension to the jQuery version was that we couldn't delay the opening of + the definition until after it loaded. We don't have that problem with our MooTools version:

      @@ -1019,25 +1168,59 @@

      Extending and Implementing Classes

      - Now we have a version of our FAQ class that allows us to get the definitions from the server. Note that we were able to integrate the new logic in a way that doesn't expand the definition until after the content comes back from the server (which we couldn't do with the jQuery version). Also note that we really only had to describe the new functionality (the ajax) and little else. This extensibility makes it possible for you to create families of plug-ins that offer different shades of functionality. It also means that you can use someone else's plug-in and alter just the bits that you to be want different if you need to (without forking it). This helps explain why, for any given design pattern - a date picker, a tab interface, etc, that you typically only find a few plug-ins for MooTools. Most of the plug-ins you get either solve your problem or, if not, you can just extend them to add the things you need. + Now we have a version of our FAQ class that allows us to get the definitions from the server. + Note that we were able to integrate the new logic in a way that doesn't expand the definition until + after the content comes back from the server (which we couldn't do with the jQuery version). + Also note that we really only had to describe the new functionality (the ajax) and little else. + This extensibility makes it possible for you to create families of plug-ins that offer different shades + of functionality. It also means that you can use someone else's plug-in and alter just the bits that + you to be want different if you need to (without forking it). This helps explain why, for any given + design pattern - a date picker, a tab interface, etc, that you typically only find a few plug-ins for + MooTools. Most of the plug-ins you get either solve your problem or, if not, you can just extend them + to add the things you need.

      - As I illustrated earlier, it's possible to write complex jQuery widgets with methods and state. Most of the code you write when doing this is vanilla JavaScript when you need to express logic that isn't related to the DOM. But jQuery's model doesn't offer a system for extending these instances into subclasses. Nor does it help you with mixins that can be reused easily. Finally, jQuery's plugins are always attached to DOM elements. If you wanted to write a class that, say, processed URLs, there's no stateful system for such a thing unless you write it yourself. + As I illustrated earlier, it's possible to write complex jQuery widgets with methods and state. Most of + the code you write when doing this is vanilla JavaScript when you need to express logic that isn't + related to the DOM. But jQuery's model doesn't offer a system for extending these instances into + subclasses. Nor does it help you with mixins that can be reused easily. Finally, jQuery's plugins are + always attached to DOM elements. If you wanted to write a class that, say, processed URLs, there's no + stateful system for such a thing unless you write it yourself.

      Decision Time

      - jQuery focuses on expressiveness, quick and easy coding, and the DOM while MooTools focuses on extension, inheritance, legibility, reuse, and maintainability. If you put those two things on opposite sides of a scale, the jQuery side translates into something with which it's easy to get started and see quick results but (in my experience) can turn into code that's harder to reuse and maintain (but really that's up to you; it's not jQuery's problem, per se), while the MooTools side takes longer to learn and requires you to write more code upfront before you see results, but afterwards is more reusable and more maintainable. -

      -

      - Further, the MooTools core does not contain every feature you can imagine and neither does the jQuery core. Both frameworks keep their cores rather lean, leaving it to you and others to write plug-ins and extensions. Their job is not to give you every feature you could want but to give you the tools so that you can implement anything you can imagine. This is the power of JavaScript, and of JavaScript frameworks in general, and both frameworks excel at it. MooTools takes a more holistic approach and gives you tools to write anything you can imagine beyond the scope of the DOM, but pays the price by having a steeper learning curve. MooTools' extensible and holistic approach gives you a superset of jQuery's features, but jQuery's focus on a slick DOM API doesn't preclude you from using the native inheritance methods of JavaScript or from using a class system like MooTools if you want it. -

      -

      - This is why I say that both frameworks are excellent choices. My effort here has been to highlight the differences in philosophies between the two codebases and highlight their advantages and disadvantages. I doubt I've been successful in keeping my preference for MooTools completely in check, but hopefully this has been helpful. Regardless of which framework you choose to work with, you now know a lot more about both, hopefully. If you have the luxury of time, I strongly recommend implementing a site with each. Then write your own review of them both and maybe your perspective will highlight some things I missed. + jQuery focuses on expressiveness, quick and easy coding, and the DOM while MooTools focuses on + extension, inheritance, legibility, reuse, and maintainability. If you put those two things on + opposite sides of a scale, the jQuery side translates into something with which it's easy to get + started and see quick results but (in my experience) can turn into code that's harder to reuse and + maintain (but really that's up to you; it's not jQuery's problem, per se), while the MooTools side + takes longer to learn and requires you to write more code upfront before you see results, but + afterwards is more reusable and more maintainable. +

      +

      + Further, the MooTools core does not contain every feature you can imagine and neither does the jQuery + core. Both frameworks keep their cores rather lean, leaving it to you and others to write plug-ins and + extensions. Their job is not to give you every feature you could want but to give you the tools so that + you can implement anything you can imagine. This is the power of JavaScript, and of JavaScript + frameworks in general, and both frameworks excel at it. MooTools takes a more holistic approach and + gives you tools to write anything you can imagine beyond the scope of the DOM, but pays the price by + having a steeper learning curve. MooTools' extensible and holistic approach gives you a superset of + jQuery's features, but jQuery's focus on a slick DOM API doesn't preclude you from using the native + inheritance methods of JavaScript or from using a class system like MooTools if you want it. +

      +

      + This is why I say that both frameworks are excellent choices. My effort here has been to highlight the + differences in philosophies between the two codebases and highlight their advantages and disadvantages. + I doubt I've been successful in keeping my preference for MooTools completely in check, but hopefully + this has been helpful. Regardless of which framework you choose to work with, you now know a lot more + about both, hopefully. If you have the luxury of time, I strongly recommend implementing a site with + each. Then write your own review of them both and maybe your perspective will highlight some things I + missed.

      A history of this document can be viewed on github.

      From 18da27c74018f0b85c7b1785f7a5985b0feaf659 Mon Sep 17 00:00:00 2001 From: Ivan Ivanov Date: Wed, 22 Aug 2012 22:49:32 +0400 Subject: [PATCH 7/8] Finally --- index_ru.html | 423 ++++++++++++++++++++++++-------------------------- 1 file changed, 207 insertions(+), 216 deletions(-) diff --git a/index_ru.html b/index_ru.html index 6b435d2..c725a78 100644 --- a/index_ru.html +++ b/index_ru.html @@ -796,19 +796,18 @@

      Повторное использование кода в jQuery

      Повторное использование кода в MooTools

      - - In MooTools when you want to define a pattern, you're more likely to use either a - Class or implement a method into a - native object (into String, for example). + В MooTools, когда вы хотите создать реиспользуемый код, вы скорее будете использовать либо + Class, либо встроите метод + в один из нативных объектов, например, String.

      - Rather than give you an almost completely different language from JavaScript's native style, - MooTools attempts to walk the middle ground between defining its own custom syntax and extending - JavaScript's own design patterns. One of the ways it does this is by extending the prototypes of the - native objects in the language and in the DOM. This means that if you needed a method to trim a string, - MooTools encourages you to add that method to String itself - (note that String.trim is - already in MooTools; you don't need to add this yourself): + Вместо того чтобы предлагать вам язык, совершенно отличный от JavaScript по стилю, MooTools + пытается балансировать между созданием своего особого синтаксиса и расширением существующих + методов JavaScript. Например, расширяет прототипы нативных объектов в самом языке и в DOM. Это + означает, что если вам, например, надо написать метод trim для обрезания строк, MooTools рекомендует + включить этот метод прямо в объект String (заметьте, что + String.trim в + MooTools уже есть, так что писать его не надо):

      String.implement({
      @@ -818,76 +817,75 @@ 

      Повторное использование кода в MooTools

      });

      - This means you can just execute " no more spaces on the end! ".trim() and get back "no more - spaces on the end!". Some would say that implementing properties into native prototypes is - inappropriate. It's the reason why MooTools and Prototype.js - can't play well with each other - any framework that manipulates prototypes of natives doesn't play - well with any other framework that does the same. If I define String.prototype.foo() and another - library on the same page defines it, too, which ever one comes last wins. In a way, this is similar to - the problem we face with the global window namespace. This is how JavaScript works. This is how - JavaScript 1.8 has added so many - features. It adds them to the prototypes. + Это означает, что вы сможете написать просто " no more spaces on the end! ".trim() и + получить "no more spaces on the end!". Некоторые скажут, что внедрение дополнительных + свойств в существующие прототипы неприемлемо. По этой причине, кстати, MooTools не может + нормально работать с Prototype.js, так как оба эти + фреймворка манипулируют прототипами нативных объектов. Если, например, я объявлю + String.prototype.foo(), и другая библиотека на этой странице объявит такую же функцию, то + победит та, которая сделает это позднее. В некотором смысле это похоже на проблему с объявлением + переменных в глобальной области видимости. Но так уж работает JavaScript. Именно так + JavaScript 1.8 добавил + так много фич — просто поместил их в прототипы.

      - The MooTools developers include a robust framework that is easy for you to extend with your own - functionality with the intention that people who include the framework in the page are going to use - it, not some other framework. It's actually kind of rude to ask users to download two frameworks. - The only reason to include two frameworks is because you want to use plug-ins from both, and in the - minds of the MooTools authors (myself included), if you want a plug-in that isn't available with the - framework of your choice, it's more appropriate for you to spend the time porting it to your - environment than to ask your users to download another framework. + На самом деле, совмещать два фреймворка и заставлять пользователей скачивать их оба довольно + нехорошо. Единственный случай, когда вам может понадобиться два фреймворка одновременно — + когда вы хотите использовать плагины из них обоих. Однако, по мнению авторов MooTools (и меня + в том числе), если вы хотите использовать плагин, которого нет в вашем фреймворке, но есть в + другом, лучше потратить какое-то время на портирование его на ваш фреймворк, нежели помещать + их оба на страницу и заставлять пользователей скачивать лишний код.

      - Once you learn how JavaScript works and see the power of extending native objects, a whole new level - of programming opens up. You can write plug-ins that alter Elements or Dates or Functions. While some - might argue that adding methods to natives this way is a kind of pollution, I'd argue that this is how - JavaScript is meant to be used. It is a design feature of the language. By attaching methods to natives - you allow your code to be concise and compartmentalized. jQuery does this too, but limits its prototype - enhancements to the jQuery object. + Когда вы понимаете, как работает JavaScript и какие возможности дает расширение нативных объектов, + вам открывается совершенно новый уровень в программировании. Вы можете писать плагины, которые + изменяют прототипы Element, Date или Function. Некоторые могут сказать, что это замусоривает + глобальные объекты, но я возражу, что JavaScript и задумывался, чтобы использоваться именно так. + Это, можно сказать, особенность его дизайна. Код получается более кратким и менее связным, + если ее использовать. jQuery делает почти то же самое, но при этом ограничивает все расширения + прототипов объектом jQuery.

      -

      - While you can easily chain multiple method calls on the jQuery object, on any other type of object you have to use - generics. For example, in jQuery if you want to trim a string and then iterate over each line, you would have to write: + Несмотря на то, что вы можете легко объединять вызовы методов в цепочку, если это методы + объекта jQuery, для других объектов вам придется использовать обычные методы. Например, если + вы хотите обрезать кусок текста с помощью функции trim, а затем пробежаться по всем его строкам, + выполняя какой-то код, вам придется написать:

      $.each( $.trim( $('span.something').html() ).split("\n"), function(i, line){alert(line);});
      -

      But because MooTools modifies prototypes, you can do this:

      +

      То же самое с помощью MooTools (так как он модифицирует прототипы):

      $('span.something').get('html').trim().split("\n").each(function(line){alert(line);});

      - Taking a look at this makes it extremely clear how powerful it is to - modify prototypes. Chaining on DOM elements isn't the only place chaining is - useful. MooTools lets you chain methods on any object, including - running a method on multiple elements at once. + Этот пример позволяет понять, какие возможности дает изменение прототипов. DOM-элементы — не + единственное место, где может пригодиться объединение методов в цепочки. MooTools позволяет + делать это с методами любых объектов, включая вызов методов, воздействующих на несколько + объектов сразу.

      -

      - The key here is that at the heart of the MooTools framework is the notion that it's there to let you - program what you want. If there's functionality that's not in the core, you can extend it and add your - own. The job of the core is not to provide everyone with every bit of functionality that they could - ever want, but to provide the tools that allow you write the things that you want. A big part of that - is making it easier to extend the prototypes of natives, and take advantage of prototypal inheritance. - You can do these things with vanilla JavaScript but MooTools makes it easier and more pleasant. - + В основе фреймворка MooTools лежит идея того, что если функциональности нет в ядре, вы всегда можете + ее расширить, и получить то, что хотели. Задача ядра — не предоставить все возможные фичи, + которые когда-либо могут вам понадобиться, а предоставить инструменты, чтобы вы могли создать эти + фичи сами. А для этого важно, чтобы можно было легко расширять существующие прототипы и использовать + преимущества прототипного наследования. Это все можно делать и на чистом JavaScript, но с помощью + MooTools это проще и приятней.

      -

      MooTools and Inheritance

      - +

      MooTools и наследование

      - Despite its name, the MooTools Class function is not really a class nor does it create them. - It has design patterns that might remind you of classes in a more traditional programming language, - but really Class is all about objects and prototypal inheritance. (Unfortunately, using words - like "class" are the most convenient way to describe these things, so for the purposes of this article, - when I refer to "classes" I'm referring to functions that return objects - which I'll call "instances" - - that inherit from a prototype.) + Несмотря на название, функция Class в MooTools не является классом и не создает никаких + классов. По виду и по способу использования она может напомнить обычные классы в более традиционных + языках программирования, но на самом деле Class целиком и полностью относится к объектам + и прототипному наследованию (к сожалению, для описания этих вещей слово "класс" подошло лучше других, + поэтому когда я буду говорить "классы", имейте в виду, что я говорю про функции, которые возвращают + объекты, которые, в свою очередь, я буду называть "экземпляры", и которые наследуются от прототипа).

      - To make a class, you pass an object to the Class constructor like this: + Чтобы создать класс, надо передать объект в функцию Class, например, так:

      var Human = new Class({
      @@ -898,38 +896,38 @@ 

      MooTools and Inheritance

      isAlive: true, energy: 1, eat: function() { - this.energy = this.energy + 1; //same as this.energy++ + this.energy = this.energy + 1; } });

      - You pass Class an object (above, we pass an object with members like "isAlive" and "eat") and - this object becomes the prototype of every instance of that class. To create an instance, you call it - like this: + Мы передаем в Class объект (со свойствами вроде "isAlive" и "eat", как у объекта выше), + и этот объект становится прототипомм для каждого экземпляра полученного класса. Чтобы создать + экземпляр, надо вызвать его вот так:

      -
      var bob = new Human("bob", 20); //bob's name is "bob" and he's 20 years old.
      +
      var bob = new Human("bob", 20); // Боба зовут Боб и ему 20 лет.

      - Now we have an instance of Human. bob has the properties of the object we defined - when we created our Human class. But the important thing is that bob has these - properties through inheritance. When we reference bob.eat, bob doesn't really have - this property. JavaScript looks at bob and he doesn't have an eat method, so it looks - up the inheritance chain and finds it on the object we passed when we created the Human class. - This is true for energy, too. At first glance this looks potentially bad; we don't want all the - humans we create to gain energy every time that bob eats. The important thing to recognize is - that the first time we assign a value to bob's energy, we assign him his own value and we no - longer look at the prototype for it. So the first time bob eats, he gets his own definition for - energy (set to 2). + Теперь у нас есть экземпляр класса Human. У bob доступны все свойства объекта, который мы + указали при создании класса Human. Важно, что все эти свойства он получил при помощи + прототипного наследования, то есть, когда мы обращаемся к bob.eat, мы обращаемся на самом деле + к свойству его прототипа, так как сам bob этого свойства не имеет. JavaScript смотрит на объект + bob, не находит в нем свойства eat, поднимается выше по цепочке наследования и находит + его у объекта, который мы передали в функцию Class, когда создавали класс Human. + То же относится и к свойству energy. На первый взгляд выглядит плохо, так как мы не хотим, + чтобы все "человеки" получали энергию, каждый раз когда bob ест. Но важно понимать, что когда + мы первый раз назначаем значение свойству bob.energy, bob получает свое собственное + свойство, и нам больше не нужно будет лезть за ним в прототип. Так что, когда bob первый раз + поест, у него появится собственное свойство (равное 2), а прототип останется нетронутым.

      bob.eat(); //bob.energy == 2

      - Note that bob's name and age are unique to him; these are assigned to him when the class is - initialized in the initialize method. + Также обратите внимание, что name и age уже являются собственными свойствами bob, так как + они назначаются ему при инициализации (см. пример выше).

      - This whole pattern may seem a little odd to you, but the value here is that we can define functionality - for a pattern and create instances of that pattern every time we need it. Each instance maintains its - own state. So if we create another instance each one is independent of the other, but inherits from - the same base pattern: + Этот подход может показаться слегка странным, но он довольно удобен, чтобы создать шаблон один раз, + а затем создавать экземпляры по этому шаблону, когда понадобится. При этом у каждого экземпляра будет + свое собственное состояние:

      var Alice = new Human();
      @@ -937,48 +935,44 @@ 

      MooTools and Inheritance

      //bob.energy == 2

      - Where things get really interesting is when we want to augment this behavior. + Но все становится еще интереснее, когда мы хотим расширить это поведение.

      -

      Extending and Implementing Classes

      - +

      Расширение и реализация классов

      - Let's revisit our jQuery faq plug-in. What would happen if we wanted to add more functionality - to that plug-in. What if we wanted to make an ajax version that fetched the answers to the questions - from the server? Let's imagine that the faq plug-in was authored by someone else and we want to - add more to it without altering it in any way (we don't want to fork it). + Давайте еще раз взглянем на наш плагин faq для jQuery. Что, если нам понадобится сделать + аяксовую версию, которая будет получать ответы на вопросы с сервера? Представим, что этот плагин + был написан кем-нибудь другим, и мы хотим модифицировать плагин, не внося изменений в исходную + версию (а форкать мы не хотим).

      - Our only real choices are to either duplicate the faq plug-in's logic entirely (remember, - it's a single function), essentially forking it, or we can invoke it and then add more logic to it. - Given a choice, the latter seems to save us the most trouble. It would look something like this: + Единственные реальные способы это сделать — либо скопировать весь его код, фактически + форкнув его (напомню, это обычная функция), либо вызвать эту функцию и затем добавить + дополнительную логику, которую мы хотели. Если выбирать, то последнее кажется менее проблематичным. + Вот как это может выглядеть:

      jQuery.fn.ajaxFaq = function(options) {
           var settings = jQuery.extend({ 
      -        //some ajax specific options like the url to request terms from
      +        // какие-нибудь опции, специфичные для ajax
               url: '/getfaq.php'
               definitions: 'dd'
           }, options); 
      -    //"this" is the current context; in this case, the elements we want to turn into faq layouts
      +    // "this" в данном случае - элементы, которые мы хотим превратить в разделы faq
           $(this).find(settings.definitions).click(function() {
      -        $(this).load(.....); //the logic to load the content from the term
      +        $(this).load(.....); // логика для загрузки контента с сервера
           });
      -    this.faq(); //call our original faq plug-in
      +    this.faq(); // вызываем оригинальный плагин
       });

      - This has some down sides. First of all, our faq class is going to repeat our selector for - the definitions, which might be expensive; there's no way to store the retrieved definitions and - pass it on for the second time they are needed. Secondly, we can't add our ajax logic into the middle - of the faq plug-in's own logic for displaying the definition. The original plug-in called - slideToggle which expands the definition using an effect. This is problematic because this - effect is going to go off before our ajax finishes loading. There's no real solution here unless we - just duplicate the entire faq plug-in. + У такого подхода есть подводные камни. Во-первых, нам придется снова пробегать весь DOM в поисках + элементов по селектору, что может быть довольно затратно, а способа сохранить выбранные объекты + и использовать их во второй раз нет. Во-вторых, мы не сможем поместить нашу логику в середину + кода плагина. А реального решения, кроме копирования всего кода, нет.

      - Now let's consider our MooTools Human class. It has properties like isAlive and - energy and it has a method called eat. What if we wanted to make a new version of - Human that had additional properties? With MooTools, we extend the class: + Теперь давайте рассмотрим наш класс Human для MooTools. Что, если нам понадобится + создать новую версию "человеков" с дополнительными свойствами? Просто расширим класс:

      var Ninja = new Class({
           Extends: Human,
      @@ -993,10 +987,11 @@ 

      Extending and Implementing Classes

      } });

      - You can see that we've added a lot of functionality here into a subclass. This subclass has all these - properties that are unique to Ninjas. Ninjas start off with an initial energy - value of 100. Ninjas get a side. They also get an attack method that lets - them kill other Humans, but it costs the Ninja energy. + Как вы видите, мы добавили достаточно много функциональности с помощью подкласса. Теперь у этого + подкласса есть как свойства его родителя, так и его собственные. Например, Ninja имеет + начальное значение энергии, равное 100, также у него есть дополнительный параметр, side + и дополнительный метод attack, который позволяет убивать других человеков, но, правда, + стоит ниндзе энергии.

      var bob = new Human('Bob', 25);
      @@ -1004,23 +999,21 @@ 

      Extending and Implementing Classes

      //blackNinja.isAlive = true //blackNinja.name = 'Nin Tendo' blackNinja.attack(bob); -//bob never had a chance
      +// у Боба не было шансов

      - Picking this apart a bit, there are some interesting things to consider here. Note that we have an - initialize method in the Ninja class. This would appear to overwrite the - initialize method in the Human class, but we can still access it by calling - this.parent, passing along the arguments that the parent class's initialize expects. - Further, we can control when our logic occurs; before or after the call to the parent. We can assign - new values to properties (like the energy value) and we can define new functionality. - Imagine if we could do this with our faq plug-in for jQuery. We could load our ajax and THEN - slide open the value. + Есть некоторые интересные вещи, которые стоит рассмотреть подробнее. Обратите внимание на метод + initialize в классе Ninja. Этот метод, очевидно, перекрывает старый метод из + класса Human, но мы все равно имеем к нему доступ через вызов функции this.parent, + передавая ей аргументы, которые ожидает метод initialize у родителя. Тем самым мы можем + контролировать, когда выполнять наш дополнительный код — до родительского или после. + Представьте, если бы мы могли сделать подобное в нашем плагине для jQuery. Тогда бы мы смогли + сначала получить данные с сервера через ajax, а затем открыть раздел faq с красивым эффектом.

      - MooTools has another pattern called a Mixin. Unlike the parent to - child relationship that is defined by extending one class into a - subclass, you can also define classes that are mixed into other - classes to imbue them with their properties. Here's an example: + В MooTools существует также и другой подход, называемый Mixin. В отличие от создания классов + и их наследования, вы можете создавать классы, чтобы потом смешивать их с другими классами, + наделяя их тем самым нужными свойствами. Например:

      var Warrior = new Class({
      @@ -1034,14 +1027,14 @@ 

      Extending and Implementing Classes

      });

      - Here we've broken the qualities that make a Ninja different from a Human and put - them in a class of their own. This lets us reuse this code outside of Ninja. We could then - imbue our Ninja class with the qualities of a warrior like so: + То есть, мы выделили свойства, которые отличают ниндзь от обычных человеков, и поместили в отдельный + класс. Это позволит использовать данный код отдельно от класса Ninja. Можно объявить класс + Ninja другим способом, отдельно указав, что он обладает качествами воина:

      var Ninja = new Class({
           Extends: Human,
      -    Implements: Warrior, //can be an array if you want to implement more than one
      +    Implements: Warrior, // можно передать массив, если классов несколько
           initialize: function(name, age, side) {
               this.side = side;
               this.parent(name, age);
      @@ -1049,7 +1042,8 @@ 

      Extending and Implementing Classes

      });

      - Ninja still works as it did before, but Warrior is at our disposal to reuse: + Ninja в этом случае будет работать совершенно так же, но теперь у нас есть класс + Warrior, и его можно использовать повторно:

      var Samurai = new Class({
      @@ -1059,104 +1053,100 @@ 

      Extending and Implementing Classes

      });

      - Now we have a Samurai class and a Ninja class. But look at how little code both - Ninja and Samurai took to define. Both of them are similar in that they are humans - with warrior qualities, but they are different in that samurais are always, always good, while ninjas - have shifting allegiances. By spending the time to write a Human class and a Warrior - class, we're able to have three different classes with no repetition of code while maintaining a very - granular level of control over when methods are called and how they relate to each other. Each instance - we create has its own state and the code itself is very legible. + Теперь мы объявили классы Samurai и Ninja. Но посмотрите, как мало кода занимают + объявления этих классов. Оба они похожи в том, что являются человеками и обладают качествами воина, + но отличаются тем, что самураи всегда-всегда хорошие, а ниндзи могут быть и плохими. Потратив время + на создание классов Human и Warrior, мы теперь с легкостью получили три различных + класса без какого-либо дублирования кода между ними. Такой подход дает возможность более тонко + контролировать, когда какие методы будут вызываться и как они друг с другом соотносятся. + Каждый экземпляр созданных таким образом классов имеет свое собственное состояние, и код получился + весьма читаемым.

      -

      - Now that you have an overview of how classes work in MooTools, let's look at our faq - class that we wrote in jQuery and write it as we would in MooTools and then extend it to add Ajax - to it just as we did with jQuery. + Сейчас, когда вы получили представление о том, как работают классы в MooTools, давайте посмотрим + на наш плагин faq для jQuery и перепишем его так, как бы мы сделали в MooTools, а потом + добавим Ajax, как мы пытались сделать в jQuery.

       var FAQ = new Class({
      -    //Options is another class provided by MooTools
      +    // Options - это еще один MooTools класс
           Implements: Options,
      -    //these are the default options
      +    // опции по умолчанию
           options: {
               terms: 'dt',
               definitions: 'dd'
           },
           initialize: function(container, options) {
      -        //we store a reference to our container
      +        // сохраняем ссылку на наш контейнер
               this.container = $(container);
      -        //setOptions is a method provided by the Options mixin
      -        //it merges the options passed in with the defaults
      +        // setOptions - это метод, предоставляемый Options,
      +        // он смешивает переданные в конструктор свойства с дефолтными
               this.setOptions(options);
      -        //we store the terms and definitions
      +        // сохраняем заголовки и тексты
               this.terms = this.container.getElements(this.options.terms);
               this.definitions = this.container.getElements(this.options.definitions);
      -        //we call our attach method
      -        //by breaking this into its own method
      -        //it makes our class easier to extend
      +        // вызываем наш метод attach
      +        // поскольку мы выделили это в отдельный метод,
      +        // класс будет проще расширять
               this.attach();
           },
           attach: function(){
      -        //loop through the terms
      +        // пробегаем по заголовкам faq
               this.terms.each(function(term, index) {
      -            //add a click event to each one
      +            // добавляем каждому обработчик события click
                   term.addEvent('click', function(){
      -                //that calls our toggle method for
      -                //the current index
      +                // вызываем наш метод toggle
                       this.toggle(index);
                   }, this);
               }, this);
           },
           toggle: function(index){
      -        //toggle open the definition for the given index
      +        // показываем/скрываем текст раздела faq по его номеру
               this.definitions[index].slide('toggle');
           }
       });
       

      - Woah. That's a lot of code. Even if we remove all the comments it's still two dozen lines long. - I already illustrated above that we could build this plug-in with roughly the same amount of code - as the jQuery version. So why is this one so much longer? Well, we've made it much more flexible. - To use the class, we just call the constructor, like this: + Ого, это довольно много кода. Если даже удалить все комментарии, все равно получится больше 20 строк. + Я уже показывал выше, что мы можем написать такой плагин, уложившись примерно в такое же количество + строк, как и с jQuery. Так почему этот код такой большой? Потому, что мы писали его с заделом на + расширение. Итак, чтобы создать экземпляр faq, просто вызовем конструктор:

      var myFAQ = new FAQ(myContainer);
      -//and now we can call methods on it if we want:
      -myFAQ.toggle(2); //toggle the 3rd element
      +// и теперь мы можем вызывать его методы
      +myFAQ.toggle(2); // показать/скрыть третий раздел
       

      - We can access methods and properties of the instance. But what about our ajax functionality? The - problem with our ajax extension to the jQuery version was that we couldn't delay the opening of - the definition until after it loaded. We don't have that problem with our MooTools version: - + Мы имеем доступ к методам и свойствам экземпляра, теперь, что насчет ajax? В нашем jQuery плагине + была проблема, что мы не могли отложить разворачивание раздела, чтобы подождать, пока он подгрузится. + Здесь же нет такой проблемы:

      FAQ.Ajax = new Class({
      -    //this class inherits the properties of FAQ
      +    // этот класс наследует свойства класса FAQ
           Extends: FAQ,
      -    //it also gets a new option in addition to the other defaults
      -    //this one for url, that we're going to append the index of the
      -    //term to; in reality we might make this more robust, but for
      -    //this example it serves the purpose
      +    // и получает дополнительное свойство к уже имеющимся дефолтным,
      +    // оно нужно для хранения url, по которому мы будем запрашивать наши разделы
           options: {
               url: null;
           },
      -    //we're going to cache the results, so if a section is opened
      -    //twice, we won't hit the server for the data
      +    // мы будем кешировать результаты, чтобы не запрашивать данные на сервере
      +    // каждый раз при открытии раздела
           indexesLoaded: [],
           toggle: function(index){
      -        //if we've already loaded the definition
      +        // если мы уже загрузили данные для этого раздела
               if (this.indexesLoaded[index]) {
      -            //just call the previous version of toggle
      +            // то просто вызываем родительский метод
                   this.parent(index);
               } else {
      -            //otherwise, request the data from the server
      +            // иначе, лезем на сервер за данными
                   new Request.HTML({
                       update: this.definitions[index],
                       url: this.options.url + index,
      -                //and when the data is loaded, expand the definition
      +                // и когда они загружены, открываем раздел
                       onComplete: function(){
                           this.indexesLoaded[index] = true;
                           this.definitions[index].slide('toggle');
      @@ -1168,67 +1158,68 @@ 

      Extending and Implementing Classes

      - Now we have a version of our FAQ class that allows us to get the definitions from the server. - Note that we were able to integrate the new logic in a way that doesn't expand the definition until - after the content comes back from the server (which we couldn't do with the jQuery version). - Also note that we really only had to describe the new functionality (the ajax) and little else. - This extensibility makes it possible for you to create families of plug-ins that offer different shades - of functionality. It also means that you can use someone else's plug-in and alter just the bits that - you to be want different if you need to (without forking it). This helps explain why, for any given - design pattern - a date picker, a tab interface, etc, that you typically only find a few plug-ins for - MooTools. Most of the plug-ins you get either solve your problem or, if not, you can just extend them - to add the things you need. - + Таким образом, мы получили версию FAQ, которая умеет забирать данные с сервера. Обратите внимание, + что мы смогли интегрировать новую логику так, чтобы раздел не открывался, прежде чем придут данные + (что мы не могли сделать с jQuery). Также заметьте, что нам пришлось всего лишь описать функциональность + ajax без особых лишних телодвижений. Это позволяет создавать целые семейства плагинов, которые + отличаются друг от друга некоторыми свойствами и функциями. Это также значит, что мы можем взять + чужой плагин и изменить в нем лишь то, что нам нужно, не форкая его. Это, кстати, объясняет то, что + для MooTools существует меньше плагинов для различных распространенных штук вроде удобного выбора даты + или интерфейса со вкладками. Большинство плагинов либо решают вашу проблему сразу, либо требуют + незначительных изменений, чтобы полностью вам подходить.

      -

      - As I illustrated earlier, it's possible to write complex jQuery widgets with methods and state. Most of - the code you write when doing this is vanilla JavaScript when you need to express logic that isn't - related to the DOM. But jQuery's model doesn't offer a system for extending these instances into - subclasses. Nor does it help you with mixins that can be reused easily. Finally, jQuery's plugins are - always attached to DOM elements. If you wanted to write a class that, say, processed URLs, there's no - stateful system for such a thing unless you write it yourself. + Как я упоминал ранее, возможно писать сложные виджеты с методами и хранением состояния и на jQuery, + но большая часть кода, которую вам придется написать, будет чистым JavaScript, поскольку не имеет + отношения к DOM. А jQuery не предлагает способа расширять свои объекты с помощью подклассов и + не поможет вам создать классы для смешивания с другими, чтобы их можно было использовать еще. + В конечном счете, все плагины jQuery всегда привязаны к элементам DOM. Если вам захочется написать + класс, который, скажем, будет обрабатывать URL'ы, вам придется писать это самому, так как готовой + системы, позволяющей хранить состояние, нет.

      -

      Decision Time

      - +

      Пора принимать решение

      - jQuery focuses on expressiveness, quick and easy coding, and the DOM while MooTools focuses on - extension, inheritance, legibility, reuse, and maintainability. If you put those two things on - opposite sides of a scale, the jQuery side translates into something with which it's easy to get - started and see quick results but (in my experience) can turn into code that's harder to reuse and - maintain (but really that's up to you; it's not jQuery's problem, per se), while the MooTools side - takes longer to learn and requires you to write more code upfront before you see results, but - afterwards is more reusable and more maintainable. + jQuery сконцентрирован на выразительности, возможности быстро и просто написать код, и на DOM, + а MooTools — на расширяемости, наследовании, читаемости, возможности повторного использования + и поддерживаемости. jQuery — это то, с чего просто начать и быстро получить результаты, но + потом, по моему опыту, это может превратиться в код, который сложно использовать повторно и + поддерживать (но, на самом деле, это уж от вас зависит, и не проблема jQuery). MooTools — + то, что сложнее изучать и требует написания большего количества кода, прежде чем вы увидите + результаты, но в итоге получившийся код, вероятно, будет легче поддерживать и использовать повторно.

      - Further, the MooTools core does not contain every feature you can imagine and neither does the jQuery - core. Both frameworks keep their cores rather lean, leaving it to you and others to write plug-ins and - extensions. Their job is not to give you every feature you could want but to give you the tools so that - you can implement anything you can imagine. This is the power of JavaScript, and of JavaScript - frameworks in general, and both frameworks excel at it. MooTools takes a more holistic approach and - gives you tools to write anything you can imagine beyond the scope of the DOM, but pays the price by - having a steeper learning curve. MooTools' extensible and holistic approach gives you a superset of - jQuery's features, but jQuery's focus on a slick DOM API doesn't preclude you from using the native - inheritance methods of JavaScript or from using a class system like MooTools if you want it. + Дальше, ядро MooTools не содержит всевозможной кучи фич, равно как и ядро jQuery. Оба фреймворка + стараются держать свои ядра компактными, давая другим возможность написать плагины и расширения. + Их задача не предоставить вам все фичи, которые могут вам пригодиться, а дать инструменты, + чтобы вы могли сами создать что вам угодно. В этом сила JavaScript, а также JavaScript фреймворков, + и оба фреймворка в этом весьма преуспели. MooTools подходит к этому более глобально, позволяя + вам писать что угодно, не ограничиваясь лишь DOM, но платит за это более высокой сложностью изучения. + Возможности MooTools включают в себя все возможности jQuery, но jQuery просто концентрируется на + "гладком" API для работы с DOM, и вовсе не мешает вам использовать стандартные средства языка для + прототипного наследования или какую-либо другую систему вроде той, что в MooTools, если хотите.

      - This is why I say that both frameworks are excellent choices. My effort here has been to highlight the - differences in philosophies between the two codebases and highlight their advantages and disadvantages. - I doubt I've been successful in keeping my preference for MooTools completely in check, but hopefully - this has been helpful. Regardless of which framework you choose to work with, you now know a lot more - about both, hopefully. If you have the luxury of time, I strongly recommend implementing a site with - each. Then write your own review of them both and maybe your perspective will highlight some things I - missed. + Вот почему я говорю, что оба фреймворка — прекрасный выбор. Я попытался показать различия + в их философии, а также их преимущества и недостатки. Вряд ли мне удалось удержать свое явное + предпочтение MooTools под контролем, но надеюсь, что этот текст был вам полезен. + Независимо от того, какой фреймворк вы выберете, теперь вы знаете больше о них обоих. + Если у вас найдется драгоценное время, очень рекомендую сделать по сайту на каждом из них. + Затем напишите свой собственный обзор, который, возможно, осветит те вещи, которые я упустил.

      -

      A history of this document can be viewed on github.


      - About me: I am a MooTools contributor and I blog about JavaScript and other things on my site Clientcide as well as release numerous plug-ins for MooTools. I am the author of MooTools Essentials as well as the MooTools online tutorial. I work at a company in the SF Bay Area called Cloudera. I can be contacted thusly. + Обо мне: Я разработчик MooTools и веду блог о JavaScript и + других вещах на моем сайте Clientcide. Также я написал + множество плагинов для MooTools. Я автор + MooTools Essentials + и MooTools online tutorial. + Я работаю в компании Cloudera. + Со мной можно связаться здесь.

      From 05651a32fe3df478ae86840bbd2e9f6fcb17588b Mon Sep 17 00:00:00 2001 From: Ivan Ivanov Date: Thu, 23 Aug 2012 14:57:53 +0400 Subject: [PATCH 8/8] Links to translations --- index.html | 2 +- index_ru.html | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/index.html b/index.html index f986717..70a42ee 100644 --- a/index.html +++ b/index.html @@ -108,7 +108,7 @@

      jQuery vs MooTools

      May, 2009 - Aaron Newton of Clientcide

      diff --git a/index_ru.html b/index_ru.html index c725a78..ed64d49 100644 --- a/index_ru.html +++ b/index_ru.html @@ -107,8 +107,12 @@

      jQuery vs MooTools

      @@ -369,7 +373,7 @@

      Больше, чем просто DOM

      вещах помимо DOM. Это, кстати, одна из причин, почему его так легко изучать, но это также ограничивает вас в предоставляемых библиотекой возможностях. Он даже просто не пытается быть чем-то большим, чем отличной системой программирования для DOM. Он не обращает внимания ни на наследование, - ни на все нативные типы в языке JavaScript, но ему этого и не нужно. Если вам нужно возится со + ни на все нативные типы в языке JavaScript, но ему этого и не нужно. Если вам нужно возиться со строками, датами, регулярными выражениями, массивами и функциями, без проблем. Просто это уже не работа jQuery. К вашим услугам обычный JavaScript. jQuery делает вам конфетку из DOM, но все остальное уже выходит за его рамки.