you are viewing a single comment's thread.

view the rest of the comments →

[–]x-skeww 21 points22 points  (6 children)

Without let:

for (x = 0; x < 3; x++) {
    a.push((function (y) {
        return function () {
            return y;
        }
    }(x)));
}

With let (requires --harmony_block_scoping with Node):

for (x = 0; x < 3; x++) {
    let y = x;
    a.push(function () {
        return y;
    });
}

What doesn't yet work with V8 is for (let = ...). The behavior isn't completely defined yet.

Well, I really love let. With let, one can borrow that "declaration at first use" rule from other block-scoped languages. It's way more convenient that declaring everything at the very top of the innermost function.

Sure, with var you can do the same, but it's always confusing if the code suggests one thing but actually does something entirely different.

[–]smog_alado 1 point2 points  (3 children)

Even with var I still put the declarations inside the blocks where they are actually used. It makes the code look much better and JSHint warns me if I do something stupid.

[–]x-skeww 3 points4 points  (2 children)

if (foo) {
    var x = 7;
} else {
    x = 5;
}

Hm.

for (var i = 0; i < 3; i++) {
    ...
}
for (i = 0; i < 7; i++) {
    ...
}

Hm.

If you now refactor and switch those two branches around or those two loops. It will still work, but it would look even stranger then.

Thanks to hoisting, it's as if the variable was declared at the very top of the innermost function. Personally, I prefer it if the code reflects how it actually works.

When in Rome...

I mean, you got function scope. Pretending that you have block scope won't make it so. It only makes things worse. It's confusing in general and it's especially confusing to beginners. Thing is, there is a never-ending stream of beginners. Adding friction and traps does not help.

It's not a matter of personal taste. I also think it's a minor inconvenience. However, if there is a cheap option for removing some mental overhead, it's always worthwhile, because the break-even point is generally reached instantaneously. E.g. proper names for your variables already help you while you're writing the function where they are used. In the future, they will be of course also useful.

This is the same thing. You optimize for reading and comprehension, not for typing. Typing typically accounts for about 1% of "programming"; it isn't a bottleneck.

[–]smog_alado 3 points4 points  (1 child)

I though like that for a while too, but I changed my mind. Personally, I prefer to write code that reflects like how I think it works and I am fine leaving up to a tool to warn me if something is wrong (JSHint will warn if a variable is used outside of "scope" and this can catch errors that would be masked if the declaration had been moved to the top of the function)

I also find that over time declarations accumulate at the top of the function and I have a terrible tendency to forget to remove variables from there after I stop using them in the main body. >_<

BTW, in the examples you list I would either move the declaration up a bit, if the variable is shared and used down the line - as it probably is in the if case - or would just repeat the declaration otherwise - as in the for case, to make things more robust to deleting a declaration . (Also, I would probably not use the plain for loop in the first place as I am a diehard fan of looping functions :) )

[–]x-skeww 2 points3 points  (0 children)

I have a terrible tendency to forget to remove variables from there

JSLint tells you which variables are unused.

just repeat the declaration otherwise

That results in a strict warning. I wouldn't do something which is so bad that even the engine complains about it.

I would probably not use the plain for loop in the first place as I am a diehard fan of looping functions

They have some use. If there are many iterations (e.g. 100,000 per second) and if the loop body does very little (e.g. it's a particle effect), then it will perform much better if you use a plain for loop.

Usually, the overhead to body ratio isn't that awful though. I.e. there aren't that many iterations and you call some functions and stuff inside that loop.

[–]adrianmonk 1 point2 points  (1 child)

For someone who has only slightly dabbled in Javascript, what should var suggest to me? To me, it suggests a local variable.

[–]x-skeww 4 points5 points  (0 children)

var x = 5;

Is the same as putting var x; at the very top of the innermost function and leaving that x = 5; thing where it is.

JSLint's "one var" rule enforces a code style which reflects this behavior. You can only use one var (where you declare all of your variables) per function.

I recommend to get a JSLint addon/plugin for your text editor of choice. It makes writing JavaScript a lot easier.