Javascript usage has gotten remarkably more sophisticated and powerful in the past five years. One aspect of this sort of functional programming I struggle with, esp with Javascript’s peculiarities, is how to make clear either through comments or code just what is happening. Often this sort of code takes a while to decipher, even if you understand the prototypal, first-class functional Javascript way. Any thoughts or techniques for making perfectly clear what your code does and how in Javascript?
I've asked this question elsewhere, but haven't gotten much response.
The use of a common library is one thing, but I think a lot of "getting" JavaScript is simply spending time writing it. Things that may seem esoteric will slowly become mundane. This is true of just about any language or framework.
Many of the idioms used in JavaScript, such as anonymous functions, literal syntax, etc. only seem strange when you are first exposed to them. I think the same rules for writing understandable C#/Java/C++/VB/etc. code apply to JavaScript - use variable names that have semantic meaning, write comments that help someone understand intent and acknowledge assumptions, be explicit, etc.
Now, if you are really asking "how can I make JavaScript understandable to someone that is not familiar with it?" you have another issue - JavaScript is JavaScript and developers just have to do the hard work of learning it before they can be proficient in it and become "at one" with it.
For example, this function may seem very strange to those that are not familiar with JavaScript, but for me (and I am certain many others) it isn't that hard to figure out:
// comments are not included *on purpose* for illustrating
// my point about the need for language knowledge
function copy(obj) {
return new (function(o) {
for(var property in o) {
if(o[property].constructor == Array) {
this[property] = [];
for(var i = 0; i < o[property].length; i++) {
this[property][i] = new arguments.callee(o[property][i]);
}
} else if(o[property].constructor == Object) {
this[property] = new arguments.callee(o[property]);
} else {
this[property] = o[property];
}
}
})(obj);
}
The fact that this function has a name helps the casual reader know what it does, but to really understand what it is doing, one has to have an understanding of why this function might be necessary, how JavaScript object properties can be referenced, what data types JavaScript supports, how constructor functions work, how anonymous functions work, etc. Only a decently deep knowledge of those things are going to help (or a library that has literally everything but the kitchen sink).
UPDATE: To those that say comments in the above sample would lend help to the developer attempting to understand it - obviously. Comments are useful and I think that is a given. The above sample code was meant to illustrate multiple JavaScript-specific idiosyncrasies that are only going to be understood by someone with deep enough knowledge about the language.
As I said in the comments on someone else's answer, my code, which I can completely understand based on my JavaScript knowledge, shouldn't need to be so commented that it becomes a substitute for language knowledge. I shouldn't have to explain, for example, where an anonymous function is or that I am using one in the above code as an anonymous constructor function and that it will alter the perceived standard behavior (to C# and Java devs) of the this keyword, all things that are going to confuse lesser JavaScript developers.
One good way to do this is to use the principles of Unobtrusive JavaScript to separate concerns. The use of jQuery as suggested by Sebastian used this principle.
Unobtrusive JavaScript
My opinion is twofold:
Learn the language. JavaScript closures and {key: {function}} are not that hard to understand. In fact, it's a pretty common dialect.
Learn the framework. jQuery, prototype, etc. are all great frameworks that tries to follow a principle of regularity and homogeneity along all the API. If you grasp this way of doing things in your own JavaScript code, things become clear.
For example, I recently needed a method for applying custom behavior to some inputs. Instead of going functional style, I extended all the <input> elements with my method (I'm using prototype), which goes in line with the rest of the prototype stuff. If one keeps these kinds of principles in mind when developing, most of the code becomes pretty straightforward.
My biggest complaint for JavaScript is to know how to organize my .js files, but that's another story.
I think it is one of the aims of those frameworks like prototype or jQuery to hide most of the JavaScript stuff. Since it is not easy to understand it, they are designed to be as easy as can be.
Therefore if you use such frameworks JavaScript gets cleaner. What I do is to write many many comments, use a lot of whitespace and lines and so on. But those {{function(){... stories remain.
Don't forget that when you write (or come across) a particularly esoteric bit of code, you should probably consider explaining what it's doing (and why it's doing it) with a quick comment, which will help anyone else who has to read the code, but who might not be literate enough in the language to understand what's actually happening.
#Jason Bunting
I've got to say I disagree that "only a decently deep knowledge" of the ins and outs of javascript will help one's understanding of your copy() example. Comments along the lines of "deep copy" or "recursive call to copy object properties" and so forth can quickly elucidate for the programmer who isn't green behind the ears but doesn't know all the particulars of Javascript's peculiarities.
I know there are a number of important concepts to pick up before you can really know Javascript, but that doesn't mean code can't be clearer at a glance.
Format your code. If you have no idea how to use it - rely on IDE ( NetBeans or WebStorm has it inbuilt ) or JS Beautyfier ( if you are still coding in Notepad, for some reason. )
Use general principles for clean code. Use brackets, stick to one code convention, use comprehensible naming scheme, comment sparingly, avoid global variables, deep nesting, long functions and esoteric code.
Make sure your IDE can recognize your code. Often this means you have to scrap module pattern aka power constructor var module = ( function () { ... } )(); in favor of classic constructor Module = function () { ... }; Module.prototype.method1 = function () { ... };
Declare vars in the beginning of function, to avoid well known problems with variable hoisting.
Replace this in constructors with better name. Which somehow shows actual object purpose. function Car() { _car = this; _car.accelerate = function () { ... }; }
Write cross-browser code for modern browsers, and, if you need support for old crap like IE8 and below - use jQuery or other framework. Avoid doing browser detection anywhere after your initializer function, if possible.
Use JS Doc, when you can - i.e. if your IDE or repo-browser supports it.
Write for debug, when your code is really complex. i.e.: do not function() { return { huge chunks of code, do not abuse chaining, do not inline things that might break.
Do not use eval, neither standalone, nor implicit eval in setTimeout or addEventListener.
Related
I have been using javascript for a while now, and have authored my first content that has been used by other people.
The main reaction has been that my content does not play well with other code.
Unfortunately javascript does not have a lot of the normal tools for creating non-conflicting libraries, like namespaces and classes.
So what are the basic standards and tools for writing non-conflicting libraries in JS?
Javascript is a beautiful and broken programing language. Many programers coming from other languages often find its nature quite confusing if not down right annoying.
Javascript is missing a lot of the tools classical languages use to create clean classes and interfaces. But this does not mean that you can't write great libraries in JS, it just means that you need to learn how to use the tools it offers.
IMO the best resources on the subject of good modular code are:
Douglas Crockford's : javascript the good parts
Adequately Good's : Module Pattern: In-Depth
Paul Irish's : 10 things I learned from the jQuery Source
In all of these, the issue of conflicting code is addressed with at least the following two practices.
IFFE Wrapper
(function(dependency , undefined ) {
...dostuff...
})(dependency)
Wrapping your library in a IFFE is incredibly useful because it makes an immediate closure.This keeps you from over-populating the global namespace.
In addition : the above code Passes in the libraries dependencies as parameters. This both improves performance, and reduces side effects. For example jQuery passes in window via:(function(window){})(window)
Last but not least, we add but don't define the parameter undefined. This is often referred to as the idiot test. If someone changed undefined somewhere else in their code it could easily cause all kinds of trouble for your library. (function(undefined) {})()fixes this by "Not defining undefined" thus making it work as intended.
Conflict Handler
var _myLibrary = window.myLibrary;//Backs up whatever myLibrary's old value was
myLibrary = function(){...dostuff...};
myLibrary.prototype = {
getConflict : function() {
return window.myLibrary === myLibrary ?
_myLibrary || false : false;
};
}
Conflict Methods are very important when you do not know what other libraries yours will be used with. The above method is similar to jQuery's 'noConflict'.
In short, getConflict returns the overwritten myLibrary variable. If nothing was overwritten, then it returns false.
Having it return false is extremely useful as it can be used in an if statement like so.
if(myLibrary.getConflict()){
var foo = Object.create(myLibrary.getConflict());
}
I have been programming JavaScript for a fair while. I haven't ever taken a course or read guides/books as to best practices, but I've seemed to figure things out pretty well as I've gone. I know that my code isn't always the shortest and cleanest, but it's made sense for me.
I recently got into object-oriented programming and think that it's a great time to jump head-first into the language. While I know that it would be in my best interest to spend a few days pouring over OOP, I have a specific question that would help me in my attempts.
Making Variables Objects
I have a PhoneGap application, for example, that includes many functions each serially listed in split-up .js files. Everything worked okay, but I would have to keep passing the same few functions between every function, and the potential for error was fine. After reading into methods and objects a little, each page evolved to this usage:
var myPage = {
myVar1 : 'value',
myVar2 : 32,
initialize : function() {
//code that initialized the variables within this object
},
doSomething : function() {
//function that would do something with myPage vars
}
//...
};
Using this methodology, each page ended up as a grand variable with many encompassed methods and variables. This cleaned up quite a bit and greatly reduced global vars, but I still don't feel as though it's perfect. My shared .js files are broken into types and many objects, each with their own functions. My first question is: is this a bad thing, and if so, why? If I could get an explanation for my specific use, it would benefit me much more than seeing optimal examples in textbooks and guides.
Making Prototypes and Classes with a Single Instance
Looking at examples provided here and across the web and dead-tree publications, I see that objects and prototypical behavior is defined as a class, then instances of the class are created. Nothing that I need to do, however, seems to fit this budget, and I'm nearly positive that it's because I'm simply not thinking in the correct paradigm. However, if I have a function that validates input, how does that fit into a better OOP methodology?
I simply have a variable/object named validate that contains the functions necessary, then put that variable in the shared file. If I were to create it as a class and create an instance of it each time that I needed to validate something, doesn't that create a lot more overhead? I don't see how it works for applications such as this.
I think that OOP is the way to go, and I want to be part of it. Thanks in advance for all answers and comments.
My first question is: is this a bad thing, and if so, why?
Competent developers avoid having functions defined in the global scope (what you do when you write function() {} inside a script) because it pollutes the global scope, where many other scripts try to do the same. Think of it as many of us trying to make a better "share()" function on the same page - only one of us will win.
I see that objects and prototypical behavior is defined as a class, then instances of the class are created. Nothing that I need to do, however, seems to fit this budget, and I'm nearly positive that it's because I'm simply not thinking in the correct paradigm
There's not much you can do there. If you have a function that validates input, then it would be better as part of the element:
someElement.validate(); // as a prototype
instead of the conventional
validate(someElement); // as a global function
I recently watched Douglas Crockford's JavaScript presentations, where he raves about JavaScript prototype inheritance as if it is the best thing since sliced white bread. Considering Crockford's reputation, it may very well be.
Can someone please tell me what is the downside of JavaScript prototype inheritance? (compared to class inheritance in C# or Java, for example)
In my experience, a significant disadvantage is that you can't mimic Java's "private" member variables by encapsulating a variable within a closure, but still have it accessible to methods subsequently added to the prototype.
i.e.:
function MyObject() {
var foo = 1;
this.bar = 2;
}
MyObject.prototype.getFoo = function() {
// can't access "foo" here!
}
MyObject.prototype.getBar = function() {
return this.bar; // OK!
}
This confuses OO programmers who are taught to make member variables private.
Things I miss when sub-classing an existing object in Javascript vs. inheriting from a class in C++:
No standard (built-into-the-language) way of writing it that looks the same no matter which developer wrote it.
Writing your code doesn't naturally produce an interface definition the way the class header file does in C++.
There's no standard way to do protected and private member variables or methods. There are some conventions for some things, but again different developers do it differently.
There's no compiler step to tell you when you've made foolish typing mistakes in your definition.
There's no type-safety when you want it.
Don't get me wrong, there are a zillion advantages to the way javascript prototype inheritance works vs C++, but these are some of the places where I find javascript works less smoothly.
4 and 5 are not strictly related to prototype inheritance, but they come into play when you have a significant sized project with many modules, many classes and lots of files and you wish to refactor some classes. In C++, you can change the classes, change as many callers as you can find and then let the compiler find all the remaining references for you that need fixing. If you've added parameters, changed types, changed method names, moved methods,etc... the compiler will show you were you need to fix things.
In Javascript, there is no easy way to discover all possible pieces of code that need to be changed without literally executing every possible code path to see if you've missed something or made some typo. While this is a general disadvantage of javascript, I've found it particularly comes into play when refactoring existing classes in a significant-sized project. I've come near the end of a release cycle in a significant-sized JS project and decided that I should NOT do any refactoring to fix a problem (even though that was the better solution) because the risk of not finding all possible ramifications of that change was much higher in JS than C++.
So, consequently, I find it's riskier to make some types of OO-related changes in a JS project.
I think the main danger is that multiple parties can override one another's prototype methods, leading to unexpected behavior.
This is particularly dangerous because so many programmers get excited about prototype "inheritance" (I'd call it extension) and therefore start using it all over the place, adding methods left and right that may have ambiguous or subjective behavior. Ultimately, if left unchecked, this kind of "prototype method proliferation" can lead to very difficult-to-maintain code.
A popular example would be the trim method. It might be implemented something like this by one party:
String.prototype.trim = function() {
// remove all ' ' characters from left & right
}
Then another party might create a new definition, with a completely different signature, taking an argument which specifies the character to trim. Suddenly all the code that passes nothing to trim has no effect.
Or another party reimplements the method to strip ' ' characters and other forms of white space (e.g., tabs, line breaks). This might go unnoticed for some time but lead to odd behavior down the road.
Depending on the project, these may be considered remote dangers. But they can happen, and from my understanding this is why libraries such as Underscore.js opt to keep all their methods within namespaces rather than add prototype methods.
(Update: Obviously, this is a judgment call. Other libraries--namely, the aptly-named Prototype--do go the prototype route. I'm not trying to say one way is right or wrong, only that this is the argument I've heard against using prototype methods too liberally.)
I miss being able to separate interface from implementation. In languages with an inheritance system that includes concepts like abstract or interface, you could e.g. declare your interface in your domain layer but put the implementation in your infrastructure layer. (Cf. onion architecture.) JavaScript's inheritance system has no way to do something like this.
I'd like to know if my intuitive answer matches up with what the experts think.
What concerns me is that if I have a function in C# (for the sake of discussion) that takes a parameter, any developer who writes code that calls my function immediately knows from the function signature what sort of parameters it takes and what type of value it returns.
With JavaScript "duck-typing", someone could inherit one of my objects and change its member functions and values (Yes, I know that functions are values in JavaScript) in almost any way imaginable so that the object they pass in to my function bears no resemblance to the object I expect my function to be passed.
I feel like there is no good way to make it obvious how a function is supposed to be called.
My background is in C and I've picked up PHP, mySQL, HTML, CSS without too much issue.
But I'm finding Javascript/jQuery surprisingly difficult to get right.
Very frustrating.
Why?
It seems to violate a number of traditional programming principles (e.g. variable scope)
Undefined variables seem to appear out of nowhere and already have values associated with them. For example (from the jQuery docs):
$("a").click(function(event) {
event.preventDefault();
$('<div/>')
.append('default ' + event.type + ' prevented')
.appendTo('#log');
});
What exactly is "event"? Do I have to use this variable name? Should I just assume that this object is magically instantiated with the right stuff and I can use any of the methods list at the JQuery API?
There seems to be bunch of random rules (e.g. return false to stop a default action, but sometimes this doesn't work?)
Non-deterministic behavior when debugging. (e.g. I refresh the browser, try something and get result X for JS variables I'm watching in Firebug. I refresh again and I get result Y?)
Very messy looking code that is hard to follow. What happens when? I'm using Firebug and Chrome Developer Tools, but I'm not getting enough visibility.
It seems like everyday there's some random JS "rule" that comes up that I've never seen before in any of my JS books or tutorials.
What do I need to do to make Javascript/jQuery more deterministic, controlled, and logical to me?
Are there any resources that explain Javascript's quirks/gotchas?
Thanks!
1) It seems to violate a number of traditional programming principles (e.g. variable scope)
You need to declare variables using var, else it will go into the global scope.
2) Undefined variables seem to appear out of nowhere and already have values associated with them (how did this happen?)
This is possibly related to 1) and/or 4).
3) There seems to be bunch of random rules (e.g. return false to stop a default action, but sometimes this doesn't work?)
You need to let the handler return false as well. E.g. form onsubmit="return functionname()". You also need to return from the "main" function, not only from a closure (a function inside a function), referring to your previous question. It would only return into the "main" function and continue on.
4) Non-deterministic behavior when debugging. (e.g. I refresh the browser, try something and get result X for JS variables I'm watching in Firebug. I refresh again and I get result Y?)
Probably the code was executed before the HTML DOM was finished populating. You need to hook on window.onload or $(document).ready() whenever you want to execute stuff during page load.
5) Very messy looking code that is hard to follow. What happens when? I'm using Firebug and Chrome Developer Tools, but I'm not getting enough visibility.
I bet that you're talking about jQuery source? It's just a large library. You should after all not worry about this when debugging. Rather worry about your own code. However, make sure that you're looking at the unminified version of jQuery's source code.
See also:
JavaScript: the bad parts
What should every JavaScript programmer know
Douglas Crockford's "Javascript: The Good Parts" was an invaluable resource. Javascript plays a lot more like Lua, Lisp, or Python than C, it just happens to LOOK like C.
Link provided to Amazon; I snagged mine from O'Reilly.
To be honest, I think you have a good understanding. Some of my hangups were similar. The way that I have been moving on is "well, if that's the way it is, then that's the way it is". Just accept the idiosyncrasies and plow forward. PHP does some of the same things (variables can show up out of nowhere, etc...). Just code the way you want to code and if it works, then great!
Then after you get to that point start breaking out the profiler and see if there's anything that you can optimize.
Here are a couple of things:
If you understand CSS, then jQuery selectors should be easy. As far as the code goes, that's straightforward too if you can deal with chaining and JSON. EDIT: also, the jQuery documentation on everything is EXCELLENT! And There is no shortage of jQuery experts here on SO to help us noobs (and hopefully we can return the favor for newer noobs).
There is a scope to work with. (Basically) anything written outside of a function or object is in global scope. If you are inside of an object or function and use var then that sets the variable's scope
Javascript isn't like a C-based language (C++ or PHP even). It uses prototypes to deal with class/object relationships rather than a subclassing scheme.
The #1 thing that threw me for a loop is that any JS that appears anywhere on the page or that was included in <script> tags is fair game. If you have a global variable in one script, you can use that same variable in a completely different script and it will work. That may be what you mean about variables showing up out of nowhere. Also, there are some DOM based variables that can just "show up" too.
Anyways, I think that if you just plow ahead, you'll get some "AHA" moments. I'm a relative noob to programming, but I continually grow as long as I don't hang up on something that doesn't have too much of an impact on actually making the code run.
It's a language based on prototypal inheritance and is influenced by functional programming languages and the paradigm so it isn't completely just OO/Procedural like other languages. Variables are implied globals unless declared with var.
Please include an example?
return false exits out of the function as with any language's return statement. preventDefault() would be the DOM method to cancel the default behaviour of a link
Javascript is used primarily on the client side. Since there are many user agents, each of them have a different implementation of the DOM, which is very inconsistent, moreso than JS itself. Again, please include a real example to get a definitive answer.
You'll find messy looking code in any language, and maybe your lack of understanding perceives the code as messy, when in fact it isn't so bad. Or maybe you're looking at some minified/obfuscated code.
I recommend http://eloquentjavascript.net/ for learning aspects of Javascript.
Things you'll learn from the link above
lambdas
closures
Prototypal inheritance
Event based programming
Debugging
DOM
"JavaScript: The Good Parts" by Douglas Crockford is a good start
In your case, the appendices ("the bad parts" and "the awful parts") might be the most interesting :)
Crockford's "Javascript: The Good Parts" gives some common JS patterns that help with variable privatization and scoping. This is for javascript in general. For jQuery I just use the API. Also the Yui Theatre videos on javascript are quite good
Javascript can be a little tricky and some of it's functional aspects confuses people. If you actually learn and understand the language you'll find it really useful, most people just randomly start using it and then just hate.
Read javascript the good parts by crockford, it's really helpful: http://javascript.crockford.com/
Also make sure you understand closure. It's a fundamental that people don't get but often use.
In terms of variable scope, there are local and global variables. One of the gotchyas of variable scope can be seen in this example:
var thisIsAGlobalVariable
function anon () {
var thisIsALocalVariable
thisIsAGlobalVariable = 5; //if you don't use the var prefix inside a fn, it becomes global
}
You are finding it difficult because:
javascript has another kind of syntax.
javascript is dificult to debug
javascript has no autocompletion like c# etc) ?or does it
javascript has illogical rules (they become logical once you are known with them)
everything can be done in 1000 ways, and when you search for a solution, you will find 2000 answers :) where c#, php mostly have a good practice function u "should/could" use
However, I started using js/jquery a half year ago, with the same reasoning as you do, and I stuck to it, and now I use it daily to enhance my webapps.
I just love it (especcially jquery). It is a life saver, I know what and where to look, I can do about anything with it.
Everything seems logical.
If I can give you one advice: javascript/jquery is a sour apple, but just hang in there, bit trough and you won't regret it.
also, a loooot of people use it and are always willing to lend a hand if needed (I know I do)
Javascript is tricky. You don't have a compiler watching your back. To compensate, unit testing becomes more important. I've been doing my unit testing with jQuery/QUnit, but I recently started using Jasmine (http://github.com/pivotal/jasmine) and I recommend it 200%. Its a great testing framework.
If you're not familiar with testing, or testing with javascript, I'd highly recommend finding unit tests for other OSS javascript projects (hopefully for code you could use) and seeing how they test it.
With unit tests, you'll make the same mistakes, but catch them much sooner and with less grief. And if your tests are good, the mistakes won't come back after you fix tham.
I don't know how much UI design you have done in C, but the event variable only shows up when it is sent by the caller and the handler needs to, well, handle the object. If you do reading on event object, the confusion in q #2 should go away.
There is no event handling in PHP, so I think you have not came across this issue in the past. JavaScript is a programming language with its own purpose, so it was designed to work for that specific purpose.
Maybe you have to link your code to an HTML onclick="event()" button to fire off as the event.
Javascript is an incredible language and libraries like jQuery make it almost too easy to use.
What should the original designers of Javascript have included in the language, or what should we be pressuring them into adding to future versions?
Things I'd like to see:-
Some kind of compiled version of the language, so we programmers can catch more of our errors earlier, as well as providing a faster solution for browsers to consume.
optional strict types (eg, being able to declare a var as a float and keep it that way).
I am no expert on Javascript, so maybe these already exist, but what else should be there? Are there any killer features of other programming languages that you would love to see?
Read Javascript: The Good Parts from the author of JSLint, Douglas Crockford. It's really impressive, and covers the bad parts too.
One thing I've always longed for and ached for is some support for hashing. Specifically, let me track metadata about an object without needing to add an expando property on that object.
Java provides Object.getHashCode() which, by default, uses the underlying memory address; Python provides id(obj) to get the memory address and hash(obj) to be customizable; etc. Javascript provides nothing for either.
For example, I'm writing a Javascript library that tries to unobtrusively and gracefully enhance some objects you give me (e.g. your <li> elements, or even something unrelated to the DOM). Let's say I need to process each object exactly once. So after I've processed each object, I need a way to "mark it" as seen.
Ideally, I could make my own hashtable or set (either way, implemented as a dictionary) to keep track:
var processed = {};
function process(obj) {
var key = obj.getHashCode();
if (processed[key]) {
return; // already seen
}
// process the object...
processed[key] = true;
}
But since that's not an option, I have to resort to adding a property onto each object:
var SEEN_PROP = "__seen__";
function process(obj) {
if (obj[SEEN_PROP]) { // or simply obj.__seen__
return; // already seen
}
// process the object...
obj[SEEN_PROP] = true; // or obj.__seen__ = true
}
But these objects aren't mine, so this makes my script obtrusive. The technique is effectively a hack to work around the fact that I can't get a reliable hash key for any arbitrary object.
Another workaround is to create wrapper objects for everything, but often you need a way to go from the original object to the wrapper object, which requires an expando property on the original object anyway. Plus, that creates a circular reference which causes memory leaks in IE if the original object is a DOM element, so this isn't a safe cross-browser technique.
For developers of Javascript libraries, this is a recurring issue.
What should the original designers of Javascript have included in the language, or what should we be pressuring them into adding to future versions?
They should have got together and decided together what to implement, rather than competing against each other with slightly different implementations of the language (naming no names), to prevent the immense headache that has ensued for every developer over the past 15 years.
The ability to use arrays/objects as keys without string coercion might've been nice.
Javascript is missing a name that differentiates it from a language it is nothing like.
There are a few little things it could do better.
Choice of + for string concatenation was a mistake. An & would have been better.
It can be frustrating that for( x in list ) iterates over indices, as it makes it difficult to use a literal array. Newer versions have a solution.
Proper scoping would be nice. v1.7 is adding this, but it looks clunky.
The way to do 'private' and 'protected' variables in an object is a little bit obscure and hard to remember as it takes advantage of closures and how they affect scoping. Some syntactic sugar to hide the mechanics of this would be fabulous.
To be honest, many of the problems I routinely trip over are actually DOM quirks, not JavaScript per se. The other big problem, of course, is that recent versions of JavaScript have interesting and useful things, like generators. Unfortunately, most browsers are stuck at 1.5. Apparantly only FireFox is forging ahead.
File IO is missing.... though some would say it doesn't really need it...