Doug Crockford discusses let
at this point in his talk, "The Better Parts".
The point is, let
avoids a source of misunderstanding, esp. for programmers with expectations set by languages with block-scope. A var
has function scope (it declares a variable that's visible throughout the function) even though it looks like it has block scope.
var
might possibly still be useful in an extreme case like machine-generated code, but I'm stretching hard there.
(const
is also new and has block scope. After let x = {'hi': 'SE'}
you can reassign to x
, while after const y = x
you cannot reassign to y
. That's often preferrable since it keeps something from accidentally changing out from under you. But to be clear, you can still modify the object y.hi = 'SO'
unless you freeze it.)
Realistically, your impression is right on for ES6: Adopt let
and const
. Stop using var
.
(In another performance of "The Better Parts", Doug says why ===
was added rather than fixing the problems of ==
. ==
produces some "surprising" results, so just adopt ===
.)
A Revealing Example
Mozilla Developer Network gives an example where var
does not work as intended. Their example is a realistic one that sets onclick
handlers in a web page. Here's a smaller test case:
var a = [];
(function () {
'use strict';
for (let i = 0; i < 5; ++i) { // *** `let` works as expected ***
a.push( function() {return i;} );
}
} ());
console.log(a.map( function(f) {return f();} ));
// prints [0, 1, 2, 3, 4]
// Start over, but change `let` to `var`.
// prints [5, 5, 5, 5, 5]
var
trips us up because all loop iterations share the same function-scoped i
variable, which has the value 5
after the loop finishes.
Another Telling Example
function f(x) {
let y = 1;
if (x > 0) {
let y = 2; // `let` declares a variable in this block
}
return y;
}
[f(1), f(-1)] // --> [1, 1]
// Start over, but change `let` to `var`.
// --> [2, 1]
let
declares block-scoped variables.
var
confuses us by referring to the same variable throughout the function.
Is a function getting a value from another function considered pure?
That depends on what the other function does, and what the calling function does. Impurity is infectious, purity isn't.
Calling a pure function doesn't change the purity of the calling function. Calling an impure function automatically makes the calling function impure also.
So, in your example, it depends on the purity of the part you left out: if that is pure, then the whole function is pure.
If this is a pure function, what is the difference from just using a global DEFAULT_SEPARATOR constant instead?
Nothing. A function that always returns the same value is indistinguishable from a constant. In fact, that is exactly how constants are modeled in λ-calculus.
Best Answer
var foo = function() {}
defines a variable that references an anonymous function.function foo() {}
defines a named functionfoo
.Either can be passed by name as function parameters and either can be instantiated if the intended use is for OOP.
At the end of the day, which one you use is largely dictated by your specific use-case (Javascript is fun like that ;)). If you end up using the former, I would strongly suggest that you name the function:
var foo = function MY_function() {}
. This naming convention helps your debugger callstack not be useless.