# JavaScript let vs var: Block Scope and Function Scope

> Compare let and var in JavaScript: let is block-scoped and var is function-scoped, with examples showing hoisting, nested scopes, and global object behavior

**URL:** https://sentry.io/answers/difference-between-let-and-var-in-javascript/

---

## The Problem

What's the difference between using `let` and `var` in JavaScript?

## The Solution

The keywords `let` and `var` both declare new variables in JavaScript. The difference between `let` and `var` is in the scope of the variables they create:

- Variables declared by `let` are only available inside the block where they're defined.
- Variables declared by `var` are available throughout the function in which they're declared.

Consider the difference between these two JavaScript functions:

```javascript
function varScoping() {
  var x = 1;

  if (true) {
    var x = 2;
    console.log(x); // will print 2
  }

  console.log(x); // will print 2
}

function letScoping() {
  let x = 1;

  if (true) {
    let x = 2;
    console.log(x); // will print 2
  }

  console.log(x); // will print 1
}
```

In `varScoping()`, one `x` variable is used throughout the function, even though an `x` variable is declared in two different places with different values.

In `letScoping()`, two distinct `x` variables are used – one appears in the main function body and another in the `if` block. This behavior remains the same if we replace the first `let` keyword with a `var` keyword:

```javascript
function varAndLetScoping() {
  var x = 1;

  if (true) {
    let x = 2;
    console.log(x); // will print 2
  }

  console.log(x); // will print 1
}
```

A `var` variable will be available thoroughout the function body in which it is defined, no matter how deeply nested its definition. A `let` variable will only be available within the same block where it is defined. See below:

```javascript
function nestedScopeTest() {
  if (true) {
    var functionVariable = 1;
    let blockVariable = 2;

    console.log(functionVariable); // will print 1
    console.log(blockVariable); // will print 2

    if (true) {
      console.log(functionVariable); // will print 1
      console.log(blockVariable); // will print 2
    }
  }

  console.log(functionVariable); // will print 1
  console.log(blockVariable); // will throw an error
}
```

This works because the `var` declaration of `functionVariable` is [hoisted](https://developer.mozilla.org/en-US/docs/Glossary/Hoisting) to the top level of `nestedScopeTest()` before execution, but the `let` declaration of `blockVariable` is not.

The behavior of `var` can be useful in some cases, but is quite different from other programming languages, and can cause difficult-to-resolve bugs. The more recently introduced `let` keyword allows for more precise and predictable variable scoping, and allows programmers to safely reuse names for temporary variables within the same function.

One final point to note is that when working outside of function bodies, at a global level, `let` does not create a property on the [global object](https://developer.mozilla.org/en-US/docs/Glossary/Global_object), whereas `var` does. Therefore:

```javascript
// Global variables
var x = 1;
let y = 2;
console.log(this.x); // will print 1
console.log(this.y); // will print undefined
```

## Further Reading

If you're looking to get a deeper understanding of how [JavaScript application monitoring](https://sentry.io/for/javascript/) works, take a look at the following articles:

- [Understanding the Performance Impact of Generated JavaScript](https://blog.sentry.io/performance-impact-of-generated-javascript/)
- [3 Ways to Improve JavaScript Applications](https://blog.sentry.io/3-ways-to-improve-javascript-applications/)
- [JavaScript Debugging Hub](https://sentry.io/answers/javascript/)
- [11 Habits of Highly Effective Developers](https://syntax.fm/show/778/11-habits-of-highly-effective-developers)

---

*Source: [sentry.io/answers/difference-between-let-and-var-in-javascript/](https://sentry.io/answers/difference-between-let-and-var-in-javascript/)*
