seanmonstar
Function.kwargs →
I get to write a lot of Python now on a daily basis, and some Python bits bleed back into my JavaScript writing. One aspect that I love is keyword arguments.
def example(name, description, url, help, error):
pass
example(name='A', url=myURL, description='An example')
Having something similar in JavaScript is possible, but requires a bit of work for a function to support it. Inspired by Python and MooTools overloadSetter, I cooked up a decorator to easily convert a function to allow keyword arguments1.
var example = function(name, description, url, help, error) {
}.kwargs();
example({ name: 'B', error: true, description: 'kwargs in javascript' });
example('C', 'args plus kwargs', { help: true, error: false });
Just like in Python, you can provide arguments the regular way, or pass in keyword arguments. You can also mix them; the last argument will be checked to see if it’s a kwargs-like object.
-
MooTools required, of course. ↩
no.de →
I love me some Python, but it’s also very tempting to be able to write JavaScript on both sides of the application. And for now, it’s free!
Chrome Crankshaft →
Chrome’s JavaScript engine, V8, just got even faster:
Overall, Crankshaft boosts V8’s performance by 50% on the V8 benchmark suite. This is the biggest performance improvement since we launched Chrome in 2008.
Node.js on Windows →
Still uses Cygwin, but now you don’t have to know about that. Simply unzip, and run node.exe.
Why Object.prototype is not the place for Hash methods
You might have heard that extending the Object.protoype is verboten. But you might realize that one of the most famous issues with extending Object can be solved with the handy obj.hasOwnProperty(key) line. Besides, developers who like picking MooTools likely do so (at least partly) because it’s much more elegant to call methods on objects than pass objects into functions. I’ve been asked why MooTools choses to keep a separate Hash class instead of putting those methods directly on the Object prototype. Here’s my reasoning for why.
Object is an Easy Hash
In JavaScript, the object literal notation makes it very easy to create hash-like structures. However, it does not provide that hash with methods to access keys, or do a forEach loop over, do a map function, and the like. Some developers might reach for the Object’s prototype to add in these useful methods. However, you might remember that all objects inherit from Object. Which essentially means everything (Array, Function, user-defined class).
Dog isn’t a Hash
Now imagine, defining a class like Dog. Or how about User, since that’s much more real-world. Does it make sense for User to inherit Hash methods? Would you in any other language write class User extends Hash? Can you imagine being able to call someUser.map(fn) or someUser.keys()? It’s silly!
You might be thinking that it doesn’t matter, you would never need to make those method calls, so they’re practically invisible. But they’re not. The point of decent code is modularize information and logic, not mix in pieces we never need.
It’s especially easy to just include the Hash class from MooTools More if you need hash capabilities. It’s 6 extra characters around your object literal, and then you don’t pollute any other class. Hurray!
Edge Prototype →
Adobe has a prototype that acts much like their Flash Pro, but generates HTML, JavaScript, and CSS.
I suspect that this will be used on most brochureware websites in the future, but there will of course still be need for optimized hand-coded solutions until browser rendering and performance is as negligible as native apps.
MVC in MooTools: Controllers
This is another installment about how to use my MooTools MVC framework. If you’re interested in the previous parts, check out my write-up on using Models and Views.
It’s often explained that Controllers are how you tie Models and Views together. I don’t want to get into that argument. For me and my framework, Controllers handle DOM events. They listen to the views for events, update models, and then render new views. Let’s take a look.
Event.Delegation
Event delegation is used throughout the controllers, since it greatly eases the pain of changing the DOM around all the time. When you name a controller, the first part of the name will be used to find or create an element to look over, unless another element is specified. Example time:
var RecipesController = new Class({
Extends: Controller
});
//attaches itself to <div id="Recipes"></div>
//if that doesn't exist, it gets created
The rest of the controller contains event handlers for everything that goes on inside that element, and methods that various event handlers can call.
var RecipesController = new Class({
Extends: Controller,
events: {
load: function() {
Recipe.findAll(this.list.bind(this));
},
'click:relay(.recipe .delete)': function(e) {
e.preventDefault();
var recipeView = $(e.target).getParent('.recipe');
recipeView.get('model').destroy(function() {
recipeView.destroy();
});
}
}
});
The load event will fire on domready, and eveything else is in the MooTools event delegation way. Currently, all event handlers are bound to the controller instead of the element, since it’s easy enough to get the element from the event object, and you’re most likely going to want to call a method of the controller. For instance, you might notice that the load event has a call to list on the controller.
this.view
First-class methods on a controller get access to the view method. This is a convenience method that will instantiate views for you, with a little auto-magic thrown in.
var RecipesController = new Class({
Extends: Controller,
// events: {},
list: function(recipes) {
$(this).set('html', this.view({ recipes: recipes }));
}
});
view can accept 2 parameters: the view name, and a data object. However, you can exclude the view name, and it will try to use the controller and method names. In the list method above, since no view name is passed to view, it will try to load recipes/list.
That’s About It
That’s all there is to Controllers, actually. They just handled events fired by Views, let appropriate Models know, and change the View if necessary. Although, while the role seems small, it tends to contain the majority of logic anyways. Models just hold on to their data, and Views just show it, but Controllers are how you manipulate it.
MooTools Core 1.3 Released →
Improved speed, improved API decisions. Lots of hard work and tears went into this. Congratulations to the MooTools team.
I’m hurriedly converting my MVC framework to use 1.3, since it fixes a few issues in IE. I could just require the compat mode, but screw that. If you still want 1.2, you can use the compat yourself.
Why is getElementsByTagName() faster than querySelectorAll()? →
Should come as no surprise if you know that getElementsByTagName returns a live NodeList, which means its grabbing a cached item from the DOM without doing much work collecting nodes.
You pay the cost later if you do much looping on that live list.