You are reading someone else JavaScript code and you find this:
var checkshit = function(a, x) {
var ret, _i, _len;
if (x == null) x = 'checked';
var ret = true;
for (_i = 0, _len = a.length; _i < _len; _i++) {
if ((x === 'checked' && !a[_i].checked) || (x === 'unchecked' && a[_i].checked)) {
ret = false;
}
}
return ret;
};
Question: WTF is this function about?
Well, if you read it like if you were a JavaScript compiler, you will eventually understand the algorithm, and then abstract it in your mind to something meaningful. But wait, you don't have all day to understand such a simple function, you should be able to understand what it does in less than 5 seconds, and understand the inner code in less than 20 seconds.
If the person that wrote that code would be less lazy when thinking about naming, it would make your life more simple. This is the same function but written with just other variable names, and some comments:
/*
* Return true if all checkboxes are 'checked' or 'unchecked'
* all(checklist, 'checked') // true if all are checked
* all(checklist, 'unchecked') // true if none is checked
*/
var all = function(checkboxes, should_be) {
var they_are, checkbox, is_checked, is_not_checked, _i, _len;
if (should_be == null) should_be = 'checked';
they_are = true;
for (_i = 0, _len = checkboxes.length; _i < _len; _i++) {
checkbox = checkboxes[_i];
is_checked = checkbox.checked; is_not_checked = !is_checked;
if ((should_be === 'checked' && is_not_checked) ||
(should_be === 'unchecked' && is_checked)) {
they_are = false;
}
});
return they_are;
};
Yes, much better, even with more lines of code, this is much more easy to read, understand and so maintain.
And it could be even better if the original programmer used a more expressive language like Coffeescript, that helps to write clean and readable code:
# Return true if all checkboxes are 'checked' or 'unchecked'
# all(checklist, 'checked') # true if all are checked
# all(checklist, 'unchecked') # true if none is checked
all = (checkboxes, should_be = 'checked') ->
they_are = yes
for checkbox in checkboxes
is_checked = checkbox.checked; is_not_checked = !is_checked
if (should_be == 'checked' and is_not_checked) or
(should_be == 'unchecked' and is_checked)
they_are = no
return they_are
Note how the first line of the function looks like:
all = (checkboxes, should_be = 'checked') ->
if you just read this, you get something like "all checkboxes should be checked", that is telling you something about the behavior of the function, isn't it?
Now, look at the if statement:
if (should_be == 'checked' and is_not_checked) or
(should_be == 'unchecked' and is_checked)
I personally find this more readable than the ugly version:
if ((x === 'checked' && !a[_i].checked) ||
(x === 'unchecked' && a[_i].checked))
Well, I see very clear in this example that in programming, NAMING MATTERS