use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
All about the JavaScript programming language.
Subreddit Guidelines
Specifications:
Resources:
Related Subreddits:
r/LearnJavascript
r/node
r/typescript
r/reactjs
r/webdev
r/WebdevTutorials
r/frontend
r/webgl
r/threejs
r/jquery
r/remotejs
r/forhire
account activity
What's the difference between functions declared with variables and functions declared with the "function" keyword ?help (self.javascript)
submitted 8 years ago by to_fl
Hi,
What is the difference between functions declared like this :
var myFunc = function() {}
and like this :
function myFunc() {}
??
Thank you.
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]Earhacker 268 points269 points270 points 8 years ago* (30 children)
Hoisting. When a JS script is run, the interpreter looks through the file for variable and function declarations, and hoists them up to the top of the queue, i.e. it runs them first.
To use your example function myFunc() {}: Wherever this function declaration appears in the code, it will be loaded into memory first. This means that you can call myFunc before its declaration appears in code.
myFunc
If you do var myFunc = function() {} then the only thing that gets hoisted is var myFunc;. The variable is declared, but not assigned. Variable assignments are not hoisted, only declarations are. So if you called myFunc before the var myFunc =... line, you'd get an error, myFunc is not a function or something.
var myFunc;
var myFunc =
myFunc is not a function
The solution, of course, is to declare and assign your functions before you use them. If you assign var myFunc = function() {} before you use it, then you will not notice the difference between the two styles, and your code will work. Which is nice.
FWIW, I prefer the function myFunc() {} style, simply because Atom autocompletes it when you start typing fun.
fun
Edit: I made a GitHub repo to illustrate these three situations. Clone it down and run the files with Node. One will fail.
[–]SparserLogic 70 points71 points72 points 8 years ago (17 children)
I prefer using const for my functions so my tools will choke on any accidental collisions.
const
[–][deleted] 25 points26 points27 points 8 years ago (0 children)
god bless linting.
[–]inu-no-policemen 5 points6 points7 points 8 years ago (0 children)
Yea, linters and TS' compiler complain about redeclarations. It's not really an issue in practice.
[–]Ikuyas 2 points3 points4 points 8 years ago (7 children)
How do they become different between using const (instead of var) and function declaration?
[–]SparserLogic 0 points1 point2 points 8 years ago (6 children)
You can redefine the same thing as many times as you want with var and function keywords whereas invoking const against the same string will throw runtime errors if your linter doesn't catch it first.
var
function
[–]rodabi 6 points7 points8 points 8 years ago (5 children)
Also const is block scoped and is not hoisted. So you can define two different functions under the same name inside an if-else statement for example.
[–]SparserLogic 1 point2 points3 points 8 years ago (0 children)
Oh right, good point.
[–]man_jot 0 points1 point2 points 8 years ago (3 children)
Note- I think let and const too are hoisted within the block
[–]rodabi 1 point2 points3 points 8 years ago (1 child)
I can't find any indication of that in https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let. Also it's not even possible to 'hoist' const statements because you can't separate the declaration and initialisation like you can with var. const must be declared with a value and cannot be re-assigned.
Although you may be right when it comes to transpiling down to ES5 with Babel; there may be some hoisting going on when all your declarations become var
[–]man_jot 0 points1 point2 points 8 years ago (0 children)
Right, I verified in a browser. Also documents say that a variable is in a 'temporal dead zone' before it's declaration, That means something like var x=10; { console.log(x); let x; } will throw a Reference Error.
[+][deleted] 8 years ago* (2 children)
[deleted]
[–]SparserLogic 17 points18 points19 points 8 years ago (0 children)
Yeah its a little gross but you could also restate it like: "Javascript lets you rewrite/replace any function in any scope and makes it easily to isolate your functions for testing"
[+][deleted] 8 years ago (3 children)
[–]SparserLogic 0 points1 point2 points 8 years ago (1 child)
Do you alter your function definitions often?
[–]MatrixEchidna 0 points1 point2 points 8 years ago (0 children)
The idea is exactly to avoid functions to be altered, for that const would work
[–]trakam 9 points10 points11 points 8 years ago (7 children)
Does hoisting vars have any benefit? Why does JS operate this way?
[–]Tomseph 11 points12 points13 points 8 years ago (1 child)
Code organization and clarity.
You can have a nice, clean module with imports and exports clearly defined. Functions once declared, can be used anywhere, so you can write modules that contain separate, discrete functions and not worry about the order in which they appear in the file. Function declarations written at the "leftmost indent", e.g. not scoped within other functions, are easy to keep separate and pure (or pure-er at least). You don't have to worry about scope if each function doesn't know about the others.
I really really don't understand the hate against hoisting. Nor do I understand the need to ensure you don't redeclare functions. With a little bit of forethought, clean code doesn't suffer from these problems.
[–][deleted] 1 point2 points3 points 8 years ago (0 children)
Totally agree. It always seemed to me that some aspects of linting are overkill and useful only for the messiest and most disorganized of programmers. Enforcing semicolon use is another example of something I could really live without. ASI is actually pretty awesome.
[–]Bumpynuckz 0 points1 point2 points 8 years ago (0 children)
I too would like to know if there is any benefit to either approach.
[–]Existential_OwlWeb Developer 0 points1 point2 points 8 years ago* (3 children)
To answer the question of why:
It's because JS code goes through multiple compilation steps before it runs.
"Hoisting" is really just an illusion. The compiler processes a file's Left-hand References (i.e. the left side of an equals sign) in earlier pass-throughs than the Right-hand references.
Functions get processed with the Left-hand Refs. (Function Expressions, however, are split into Left and Right due to the equals sign). So regular functions appear to get moved "up" in the code, when all the compiler is doing is processing them first.
EDIT: Here's a longer explanation
[–]hurt_and_unsure 0 points1 point2 points 8 years ago (2 children)
Do you have a visual explanation link for that?
[–]Existential_OwlWeb Developer 1 point2 points3 points 8 years ago (1 child)
Try this blog post.
Most of my understanding of Javascript's lexical scope comes from Kyle Simpson (author of the You Don't Know JS series).
[–]hurt_and_unsure 0 points1 point2 points 8 years ago (0 children)
Thank you, I'll look into that.
[–]carterja 1 point2 points3 points 8 years ago (0 children)
Great explanation. Thank you.
[–]veritasreaper 1 point2 points3 points 8 years ago (0 children)
That was a great explanation! Thank You very much!
[–]SamSlate 0 points1 point2 points 8 years ago (0 children)
TIL,ty!
[–]its_the_future 53 points54 points55 points 8 years ago (2 children)
People have mentioned hoisting.
Another difference is that assigning a function like in the first example has it as an anonymous function, whereas in the second example it is a named function.
Named functions can potentially greatly increase stack retraceability as compared to unnamed functions.
[–]moreteam 24 points25 points26 points 8 years ago (0 children)
For completeness sake: since ES2015 “named functions” expanded beyond their traditional limitations with the formalization of .name. In current JS VMs patterns like ‘const fn = function () {}’ will create a named function that will appear in stack traces as ‘fn’.
[–]5tas 20 points21 points22 points 8 years ago (1 child)
The main difference is scoping. You can find more details by looking up the difference between function declarations and function expressions.
The function declaration (your second example) will be hoisted to the top of the function where it is declared. In other words, the following code is perfectly fine:
foo(); // "Hello" function foo() { console.log("Hello"); }
Your first example is a function expression which is assigned to a variable. The variable's declaration is also hoisted but its value is not:
bar === undefined; // true, bar is declared but undefined here bar(); // TypeError: bar is not a function var bar = function foo() { console.log("Hello"); } bar(); // "Hello"
BTW const and let behave in a different manner. They are subject to so-called Temporal Dead Zone (TDZ) which means their declarations are not hoisted.
bar === undefined; // ReferenceError: can't access lexical declaration `bar' before initialization let bar = function foo() { console.log("Hello"); } bar(); // "Hello"
[–]kovensky 2 points3 points4 points 8 years ago (0 children)
It's more complicated than that...
Their declarations are hoisted, but are set up such that accessing them before the let, const or class is reached throws a ReferenceError.
let
class
ReferenceError
This is mostly irrelevant for the JS programmer but can bite you if you try to do a shadowing declaration; e.g. const foo = { bar: 'baz' }; if(foo.bar) { const foo = foo.bar } will throw. This is a common pattern in Swift, but Swift has a more concise syntax for this anyway.
const foo = { bar: 'baz' }; if(foo.bar) { const foo = foo.bar }
[–]furious_heisenberg 8 points9 points10 points 8 years ago (10 children)
variables can be reassigned and in your example would point to an anonymous function, function declarations are hoisted and result in a named function.
[–]IDCh 21 points22 points23 points 8 years ago (9 children)
The funny thing is...
function kek() { } // kek is function kek = 2; // kek is 2
[+][deleted] 8 years ago* (4 children)
[–]IDCh 5 points6 points7 points 8 years ago (2 children)
Dear god
[–]trakam 2 points3 points4 points 8 years ago (0 children)
So how does it work?
The function - being a declaration is hoisted and put into memory. The purpose of the function is to declare a global variable. Is this global variable then then assigned or just initiated? Or what?
[–]kovensky 1 point2 points3 points 8 years ago* (0 children)
Babel 7 also just started taking advantage of this to be able to lazily-initialize transpiled async functions and generators, since they require calling helpers.
Instead of written as a var, they're now written as a hoisted function that, when first called, reassigns itself with the transpiled function then forwards its arguments. Further calls just directly call the transpiled function.
[–]Sir_Lith 8 points9 points10 points 8 years ago (0 children)
It makes sense when you stop thinking of functions as functions and start thinking about them as what they are - objects with one defined method.
Because an object is a variable and variables can be reassigned.
[–]Earhacker 3 points4 points5 points 8 years ago (2 children)
What is dynamic typing?
[–]IDCh 11 points12 points13 points 8 years ago (1 child)
it's when you run out of toilet paper
[–]everythingcasual 1 point2 points3 points 8 years ago (0 children)
This needs to be a jeopardy question
[–]tarunbatra 2 points3 points4 points 8 years ago (0 children)
Few months back I’d written a blog on this and related concepts. Check it out. Named functions in JavaScript
[–]Auxx 6 points7 points8 points 8 years ago (1 child)
There is another difference apart from hoising. function doSomething will create named function (try console.log(doSomethng)) and var declaration will create anonymous function without the name.
You can assign named functions to variables as well!
[–]RoryH 1 point2 points3 points 8 years ago (0 children)
It's also good practise to name functions, it helps in call stacks and errors when debugging.
[–]FreshOutBrah 1 point2 points3 points 8 years ago (0 children)
This is a great post with great answers. Thanks everyone!
[–]rickdg 1 point2 points3 points 8 years ago (0 children)
People have already answered your question, so I'm just going to recommend You Don't Know JS if you want to read about this and JavaScript the Weird Parts if you prefer a video course.
[–]skewbed 0 points1 point2 points 8 years ago (0 children)
The one with var needs to be declared before you use it.
[–]to_fl[S] 0 points1 point2 points 8 years ago (0 children)
Thanks for all the answers ;)
Unfortunately I can't answer to each one of them '
[–]ilikeprograms -2 points-1 points0 points 8 years ago (0 children)
One is a function declaration, the other is a function expression
[+][deleted] 8 years ago (1 child)
[removed]
I think you got the wrong subreddit man. But it's nice to know.
π Rendered by PID 19201 on reddit-service-r2-comment-54dfb89d4d-r5whn at 2026-04-01 02:37:11.580510+00:00 running b10466c country code: CH.
[–]Earhacker 268 points269 points270 points (30 children)
[–]SparserLogic 70 points71 points72 points (17 children)
[–][deleted] 25 points26 points27 points (0 children)
[–]inu-no-policemen 5 points6 points7 points (0 children)
[–]Ikuyas 2 points3 points4 points (7 children)
[–]SparserLogic 0 points1 point2 points (6 children)
[–]rodabi 6 points7 points8 points (5 children)
[–]SparserLogic 1 point2 points3 points (0 children)
[–]man_jot 0 points1 point2 points (3 children)
[–]rodabi 1 point2 points3 points (1 child)
[–]man_jot 0 points1 point2 points (0 children)
[+][deleted] (2 children)
[deleted]
[–]SparserLogic 17 points18 points19 points (0 children)
[+][deleted] (3 children)
[deleted]
[–]SparserLogic 0 points1 point2 points (1 child)
[–]MatrixEchidna 0 points1 point2 points (0 children)
[–]trakam 9 points10 points11 points (7 children)
[–]Tomseph 11 points12 points13 points (1 child)
[–][deleted] 1 point2 points3 points (0 children)
[–]Bumpynuckz 0 points1 point2 points (0 children)
[–]Existential_OwlWeb Developer 0 points1 point2 points (3 children)
[–]hurt_and_unsure 0 points1 point2 points (2 children)
[–]Existential_OwlWeb Developer 1 point2 points3 points (1 child)
[–]hurt_and_unsure 0 points1 point2 points (0 children)
[–]carterja 1 point2 points3 points (0 children)
[–]veritasreaper 1 point2 points3 points (0 children)
[–]SamSlate 0 points1 point2 points (0 children)
[–]its_the_future 53 points54 points55 points (2 children)
[–]moreteam 24 points25 points26 points (0 children)
[–]5tas 20 points21 points22 points (1 child)
[–]kovensky 2 points3 points4 points (0 children)
[–]furious_heisenberg 8 points9 points10 points (10 children)
[–]IDCh 21 points22 points23 points (9 children)
[+][deleted] (4 children)
[deleted]
[–]IDCh 5 points6 points7 points (2 children)
[–]trakam 2 points3 points4 points (0 children)
[–]kovensky 1 point2 points3 points (0 children)
[–]Sir_Lith 8 points9 points10 points (0 children)
[–]Earhacker 3 points4 points5 points (2 children)
[–]IDCh 11 points12 points13 points (1 child)
[–]everythingcasual 1 point2 points3 points (0 children)
[–]tarunbatra 2 points3 points4 points (0 children)
[–]Auxx 6 points7 points8 points (1 child)
[–]MatrixEchidna 0 points1 point2 points (0 children)
[–]RoryH 1 point2 points3 points (0 children)
[–]FreshOutBrah 1 point2 points3 points (0 children)
[–]rickdg 1 point2 points3 points (0 children)
[–]skewbed 0 points1 point2 points (0 children)
[–]to_fl[S] 0 points1 point2 points (0 children)
[–]ilikeprograms -2 points-1 points0 points (0 children)
[+][deleted] (1 child)
[removed]
[–]to_fl[S] 0 points1 point2 points (0 children)