72

I have read, and discovered through my own experience, that JavaScript doesn't have a block scope. Assuming that the language was designed this way for a reason, can you explain to me what is that reason?

I've looked around on Google and here, but the posts I have found just reiterate that JS has a function scope and not block scope, without explaining why. I'm curious to know why this is actually the case.

Michele La Ferla
  • 6,775
  • 11
  • 53
  • 79
mricci
  • 953
  • 1
  • 7
  • 13
  • 4
    The functional programming style in JavaScript doesn't encourage it I suppose plus JS was a rushed concept, but `let` is coming in ES6 so we will have block scope in the near future. Firefox already has support for `let`. – elclanrs Jun 26 '13 at 04:48
  • The originator of the language answered the question and the explanation by @Aadit and myself seems to cover any other issues so I would consider it no longer opinion only. – mplungjan Jun 26 '13 at 07:48

4 Answers4

114

Converting my comment to answer

Choice of the creator: I tweeted Brendan and got the following answer:

@mplungjan 10 days did not leave time for block scope. Also many "scripting languages" of that mid-90s era had few scopes & grew more later.


That said, here are some relevant points:

Important: JavaScript prior to ECMAScript2015 (6th edition) does not have block scope. Variables introduced within a block are scoped to the containing function or script, and the effects of setting them persist beyond the block itself. In other words, block statements do not introduce a scope. Although "standalone" blocks are valid syntax, you do not want to use standalone blocks in JavaScript, because they don't do what you think they do, if you think they do anything like such blocks in C or Java.

we can artificially introduce scopes by creating new functions and immediately invoking them

let and const declared variables are hoisted but they are not initialized to undefined in the same way var is. Hence, referencing a let or const declared variable before its value is assigned raises a ReferenceError.

Redeclaration of the same variable in the same block scope raises a SyntaxError.

Alireza
  • 10,237
  • 6
  • 43
  • 59
mplungjan
  • 169,008
  • 28
  • 173
  • 236
  • I didn't quite understand "`let` and `const` declared variables are hoisted but they are not initialized to `undefined`" until I looked at this code example. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let#Another_example_of_temporal_dead_zone_combined_with_lexical_scoping Are you talking about the temporal dead zone with that statement? – christo8989 Aug 08 '19 at 21:05
15

New answer as of 2015. ES6 does have block scope for variable definitions with the let and const keywords.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • 2
    Unfortunately some users might still live in 2010, so relying on a brand new language feature is not the best practice. – riv Aug 05 '15 at 13:25
  • 1
    @riv - Javascript is not only used in browsers where you have to code to the lowest common denominator. It can be used in environments like node.js where you control your entire execution environment and can use `let` now. Or, you can use one of the transpilers that lets you write code in ES6 and the transpiler converts it to ES5 compatible code so it will run in older browsers. – jfriend00 Aug 05 '15 at 14:37
  • Not a new answer, cause Js have block scope with `try/catch` from **ES3** – Trung May 04 '16 at 08:57
  • @Trung - Can you provide a reference that explains that? I don't see any evidence of block scope for variable definitions. – jfriend00 May 04 '16 at 15:48
  • I read it at [You don't know Js series](https://github.com/getify/You-Dont-Know-JS/blob/master/scope%20%26%20closures/ch3.md#trycatch). – Trung May 04 '16 at 17:46
  • 1
    @Trung - That's a very special case (only in `catch` handlers that is not likely what the OP was asking about and cannot be used in any general purpose way to make block scoped variables of your own in regular blocks in ES3. If you think that answers the OP's question, then feel free to make your own answer. – jfriend00 May 04 '16 at 17:49
  • Shouldn't this answer say `let` and `const` are block scoped? – christo8989 Aug 08 '19 at 21:30
  • @christo8989 - Sure. – jfriend00 Aug 09 '19 at 01:48
11

Block scope was not implemented for the following reasons:

  1. It's makes the language easier to implement. JavaScript was initially designed as a language for writing interactive web applications. Hence it needed to be small and easy to implement.
  2. Block scopes introduce a performance hit to dynamic languages like JavaScript. This is because when you try to access some variable which is not in the current scope JavaScript first checks the current scope, then the parent scope and so on until it either finds the variable or reaches the end. Hence the introduction of block scopes would make variable access in loops and nested loops very slow.
  3. The lack of block scopes makes it easier to write programs. For example say you want to create a variable only if a certain condition is true. All you need to do in JavaScript is declare and define the variable within an if statement. In languages like C you would have to declare the variable outside the if statement and define it within the if statement.
  4. The lack of block scopes allow declarations to be hoisted. This is especially useful in the case of function declarations. For example see this fiddle: http://jsfiddle.net/L6SgM/ (note however that this example doesn't work in Firefox).
  5. Since JavaScript supports first-class function expressions we don't need block scopes. They can be simulated using immediately invoked function expressions.
Aadit M Shah
  • 72,912
  • 30
  • 168
  • 299
  • 3
    "Block scopes introduce a performance hit to dynamic languages like JavaScript." -- this is a property of an implementation, not a language. Maybe it held for the very first JavaScript implementation, but no engine written in the past ten years should suffer from it. – Marijn Jun 26 '13 at 12:05
  • #5) strictly speaking, we don't "need" block scopes any more than we needed JavaScript in the first place ... thankfully the ECMA team seems to disagree by adding support for block scopes via the 'let' keyword ... simpler language constructs are always welcome. – Jorge Garcia Jun 25 '15 at 04:46
  • 3
    `I` : Could you give us the sources that prove Brendan Eich didn't implement block scopes in Javascript for the 5 reasons you mention? I suspect you are mixing historical reasons (#1) with your reasons (#2 to #5) . . . `II` : #3 is wrong: The variable is always created, only its initialization is conditional (see: https://jsfiddle.net/paercebal/yvwhu7r0/ ). #4 is bogus (adding `"use strict" ;` in Chrome gives the error: `Uncaught SyntaxError: In strict mode code, functions can only be declared at top level or immediately within another function.`). #5 is a dirty workaround. . . . – paercebal Aug 06 '15 at 21:54
  • It may make writing programs easier, but certainly not maintaining them. – mbomb007 Mar 23 '18 at 22:02
0

There are many reasons, but some that come to mind are to aid in parsing/debugging code that uses object literals (which can sometimes look like a block), and to simplify the garbage collection of local variables.

I hope that the promised support (discussed here, for example, http://esdiscuss.org/notes/2012-07-25) turns out to be real because it would be very convenient to use variables like i that were local to only a single loop.

Joseph Myers
  • 6,434
  • 27
  • 36