-1

When defining a global function, should I use var, let, or const?

var fn = function () {};
let fn = function () {};
const fn = function () {};

I'm here thinking primarily of global functions in the C/Pascal sense, i.e. a function that is available/visible, by name, in the rest of the current file.

When I was learning JavaScript we used either var fn=.. or functino fn ().., and I'm trying to update my knowledge since browsers are now supporting ECMAScript 6 natively.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
thebjorn
  • 26,297
  • 11
  • 96
  • 138
  • 1
    What are you trying to achieve? – guest271314 Apr 30 '17 at 17:05
  • Just to define a function I can use by name anywhere in the current module. I was thinking that the function name wouldn't change once written, but I can imagine situations where that might not be the case. – thebjorn Apr 30 '17 at 17:09
  • Why would the function name or reference change? The selection of option would depend on the context of use of identifier; whether function or other value that is referenced by identifier, yes? `const` type cannot be changed, `const` cannot be deleted. – guest271314 Apr 30 '17 at 17:11
  • That is, that am aware of, `const` initial type of object cannot be changed to another type, and `const` cannot be de-referenced or deleted from current scope, see [Is it possible to delete a variable declared using const?](http://stackoverflow.com/questions/42424019/is-it-possible-to-delete-a-variable-declared-using-const?) – guest271314 Apr 30 '17 at 17:17
  • The question is inaccurate on the most important part, 'anywhere in the current module'. Module scope isn't global scope. – Estus Flask Apr 30 '17 at 17:18
  • For the same reason that any global variable changes value, but e.g. (lame example) assigning a global `logfn` either `colorlogfn` or `nocolorlogfn`.. – thebjorn Apr 30 '17 at 17:18
  • Why would you need to change a _constant_ variable? If the variable is an array or object, the properties of the array or object can be changed. What would be the purpose for changing the name of a function reference? _"either `colorlogfn` or `nocolorlogfn`"_ `colorlogfn` and `nocolorlogfn` are two different functions, yes? – guest271314 Apr 30 '17 at 17:19
  • @estus sorry, but you're correct that I don't know how to define a module scoped vs a global scoped variable... – thebjorn Apr 30 '17 at 17:21
  • It *is* module scope and not global if you're using modules. To make a global in modular environment, it should be `window.fn = ` or `global.fn = ` for Node. It's totally unclear what's your case and what you're trying to do, that's the reason why the question attracts downvotes and closing votes. – Estus Flask Apr 30 '17 at 17:26
  • _"I'm here thinking primarily of global functions in the C/Pascal sense, ie. a function that is available/visible, by name, in the rest of the current file."_ Not certain what question is? – guest271314 Apr 30 '17 at 17:32
  • @estus thanks for the explanation. I noticed most of the close votes were for "primarily opinion based", which wasn't anywhere near my intention.. – thebjorn Apr 30 '17 at 17:33
  • _"which wasn't anywhere near my intention."_ Intent is irrelevant. The question is not clear. What is the issue that you are trying to resolve? – guest271314 Apr 30 '17 at 17:33
  • 1
    @guest271314 I'm just trying to learn to use es6 correctly/idiomatically. (1 close vote for unclear, 3 for opion). Please take my lack of clarity as a lack of understanding, which it is, and not that I'm trying to be obtuse.. – thebjorn Apr 30 '17 at 17:36
  • "correctly" is different from "idiomatically". The context is just as relevant as the concept of ability to select an appropriate method to declare a variable. It depends on the context in which you are performing tasks and expecting specific outcomes of procedures. You find or define your own "correct" approach, barring syntax errors or absurd results or side-effects. – guest271314 Apr 30 '17 at 17:39
  • 3
    'global functions in the C/Pascal sense' - it's not called global in JS, it's module scope, and it doesn't really differ from function scope or other local scope in JS. it's just `function` or `const` if it needs to be declared once (`const` provides a safeguard against accidental reassigning) or `let` if it should be conditionally assigned. Notice that `function` declaration is hoisted, so it can be moved to the bottom for readability, while `const` and `let` can't. – Estus Flask Apr 30 '17 at 17:39
  • 1
    @estus thanks, that cleared up a whole bunch of issues :-) – thebjorn Apr 30 '17 at 17:45
  • 1
    The last edit to Question, from perspective here, provides context to inquiry. – guest271314 Apr 30 '17 at 17:47
  • @peter-mortensen thanks for the edits (although I'm pretty sure let/const/var implies "or" not "and"). I think (and google seems to agree) that "es6" is more common than ECMAScript 6, but I'm sure the latter is technically more correct (obligatory, https://www.youtube.com/watch?v=hou0lU8WMgo) – thebjorn May 24 '17 at 20:21

3 Answers3

5

In short: I would recommend you to use const. Why?

(In the following examples, assume we are in a browser environment.)

Function declarations/statements

They are hoisted and become properties of the global object.

fn(); // No error
function fn() {}
console.log('fn' in window); // true

Function expressions with var

They are not hoisted, but a variable declared in the global scope always becomes a property of the global object.

fn(); // TypeError
var fn = function () {};
console.log('fn' in window); // true

Function expressions with let

They are not hoisted, they do not become properties of the global object, but you can assign another value to your variable. Since JavaScript is loosely typed, your function could be replaced by a string, a number, or anything else.

fn(); // ReferenceError
let fn = () => {};
console.log('fn' in window); // false
fn = 'Foo'; // No error

Function expressions with const

They are not hoisted, they do not become properties of the global object and you cannot change them through re-assignment. Indeed, a constant cannot be redeclared.

fn(); // ReferenceError
const fn = () => {};
console.log('fn' in window); // false
fn = 'Foo'; // TypeError
Badacadabra
  • 8,043
  • 7
  • 28
  • 49
3

You should be using const unless there is a compelling reason you need to use let. You should stop using var entirely.

But usually, I'd avoid function expressions entirely and use a function declaration instead:

// Use this
function myFunc() {
  // do stuff
}

// Instead of this
const myFunc = function() {
  // do stuff
}
Brennan
  • 5,632
  • 2
  • 17
  • 24
  • 2
    no, it depends, if the value (function) changes. – Nina Scholz Apr 30 '17 at 17:04
  • 3
    And that would be a compelling reason. I assume he understands that a `const` is indeed immutable. – Brennan Apr 30 '17 at 17:05
  • Any particular reason why you would use a function declaration instead of a fn. expression? – thebjorn Apr 30 '17 at 17:13
  • 1
    Personal style, really. I prefer declarations because of hoisting. Some people tend to find that unpredictable behavior, but I disagree. Obviously, there are situations where function expressions are necessary, but I tend to use declarations where I can. – Brennan Apr 30 '17 at 17:17
  • Good point, thanks for the correction. Real immutability in JS requires more work than just throwing `const` in front of your variable. That said, you should be attempting to write your code in such a way that all variables are `const`s – Brennan Apr 30 '17 at 17:22
  • 1
    @Brennan _"you should be attempting to write your code in such a way that all variables are `const`s"_ What would be purpose of defining _all_ variables using `const`? `const n = 1; n += 1;//Uncaught TypeError: Assignment to constant variable.` – guest271314 Apr 30 '17 at 17:26
  • Javascript is well suited to writing in a functional style, which means that you shouldn't *need* to have an incrementer variable like that. One of the things that has made me a better javascript developer is attempting to write as functionally as possible. Not *everything* can be `const`, there are going to be exceptions, but you'd be surprised at how little you need `let` if you just think about your code a different way – Brennan Apr 30 '17 at 17:44
  • Actually, now that I think about it, I feel confident that one could solve just about any problem with only `const` variables. – Brennan Apr 30 '17 at 17:48
3

Eric Elliot writes:

const is a signal that the identifier won’t be reassigned.

let, is a signal that the variable may be reassigned, such as a counter in a loop, or a value swap in an algorithm. It also signals that the variable will be used only in the block it’s defined in, which is not always the entire containing function.

var is now the weakest signal available when you define a variable in JavaScript. The variable may or may not be reassigned, and the variable may or may not be used for an entire function, or just for the purpose of a block or loop.

From https://medium.com/javascript-scene/javascript-es6-var-let-or-const-ba58b8dcde75

So, best practice is to use const because function shouldn't be redeclared.

rie
  • 286
  • 2
  • 5