Skip to content
bebraw edited this page Apr 13, 2013 · 11 revisions

Even though you can plenty done with JavaScript it isn't without problems. ES6 aims to alleviate some of those. There are all sorts of solutions depending on how far you want to go.

Globals and Other Nasties

As you probably know by now all variables are global by default. You will have to use var keyword to explicitly mark them as global. To quote certain Ackbar, "it's a trap". There are a couple of ways to deal with the issue. I'll start with a conventional one. Consider the example below.

function mathMagic(items, b, c) {
    var fac = 5;
    var rx, ry, rz, ret;

    ret = items.map(function(v) {...});
}

As seen above I prefer to group my variables at top of a function by default. They might get some default values or not. There are some people that use just one var and then group the variables using that nifty , syntax. In any case it is a good convention to have.

This doesn't eliminate the issue totally. It can be very beneficial to configure your editor to highlight globals as red or some annoying color (maybe pink?).

Strict mode can be very helpful as well. It changes the behavior of the language a bit and makes it easier to spot errors such as this one. Nicholas Zakas' post on the issue likely provides some extra enlightenment.

Tools such as JSLint and its less opinionated little brother JSHint allow you to spot certain groups of problems quite easily. I recommend picking either one and hooking it up with your editor. You'll save some time and maybe develop that bald a bit later rather than sooner.

If you are really obsessed, maybe it's time to write a transpiler or use some existing one. After all, what could you not solve by writing code that writes code? That's yet another bag of problems, though. In practice simple code transformation tools can be nice, though. Just keep your cool with it.

Function Syntax Is Cumbersome

It can be a bit boring to write that function always, particularly if you enjoy using anonymous functions. Speaking of which it may be handy to name your functions even if you use them as callbacks like below:

$('.clickety').on('click', function clickety() {
    console.log('Clickety click');
});

I am leveraging jQuery selector syntax here. When an element with class "clickety" is clicked, it should print "Clickety click" to the console.

Of course this doesn't solve the original issue I was complaining about. In fact we have even more noise in the code right now. In this particular case we might be able to rewrite the function using bind using console.log.bind(console, 'Clickety click'). Even that can be optimized further. Lazy ones of us would just rewrite console.log (console.log = console.log.bind(console)) and then define partial that internally uses bind. In this case you may want to leverage arguments feature discussed at the earlier chapter.

If you are willing to accept the visual noise, you can most likely configure your editor to help you write functions faster. Ie. in vim you might want to just define abbr fn function at your .vimrc. I am certain there are some nicer solutions around as well.

sweet.js provides another solutions: macros. It allows you to replace the function keyword with def. Using sweet introduces a new dependency to your project and you will also need to compile your code to real JavaScript before you are able to use it in your browser. This isn't as big a problem as it sounds, though. You will most likely end up doing some sort of compilation pass anyway, particularly if your project is a big one. Besides trivial stuff like this macros allow you to implement way more complex features on top of the core language. Whether or not that is a good idea is debatable, though.

There might be something better in sight thanks to ES6. This something is also known as "fat arrow". As illustrated by Angus Croll, the syntax is quite simple. Consider the examples below I borrowed from his blog post:

var fat1 = () => {};
var long1 = function() {};
 
// return the square
var fat2 = x => x * x;
var long2 = function(x) {return x * x};
 
// add two numbers
var fat3 = (a, b) => a + b;
var long3 = function(a, b) {return a + b};

// return a new array containing the squares of the original...
[1, 2, 3, 4, 5].map(x => x * x); // [1, 4, 9, 16, 25]

Now try thinking what the examples above would look like in vanilla JavaScript. Yes, it would be quite verbose. Sometimes you can hide the complexity behind utility functions. bind comes in handy yet again.

This is still very bleeding edge. The specification is till work in progress. As things start to settle down I expect that people will begin to use transpilers (ES6 -> ES4) that allows them to use the subset of functionality they want. Esprima is one popular starting point for this type of work.

You can try to parse it by hand as I did in mojs but that is an approach I just cannot recommend. You will want to use something that provides AST level support and allows you to hack in the level of a language definition.

Arguments Are Undefined by Default

TBD.

Pyramid of Doom

Promises, futures, rx, q.

Not All Things Are Equal

== (coerces) vs. === (does not coerce)

Modularity

TBD

No Operator Overloading

TBD

Not Invented Here

Hard to find libs. Use JSter and other services. NPM for Node. Link to modules (next topic)

Conclusion

TBD

Clone this wiki locally