const ?let ? var ?

184 阅读3分钟

作用域

不了解作用域的倔友,可以移步你不知道的js作用域

  1. var

    • var在函数作用域内有效,并且能在函数外被访问(如果定义在全局作用域)。

    • 例如:

function testVar() {
  var a = 1;
  if (true) {
    var b = 2;
  }
  console.log(a); // 1
  console.log(b); // 2,在函数内任何地方都可访问到 b
}
testVar();
console.log(a); // 报错,a is not defined,在函数外无法直接访问到 a,但如果 a 定义在全局作用域则可以被访问
  1. letconst

    • 在块级作用域(如花括号内)有效。

    • 例如:

function testLetConst() {
  let c = 3;
  const d = 4;
  if (true) {
    let e = 5;
    const f = 6;
  }
  console.log(c); // 3
  // console.log(e); // 报错,e is not defined,在外部无法访问块级作用域内的 e
  // console.log(f); // 报错,f is not defined,在外部无法访问块级作用域内的 f
}
testLetConst();

重新赋值与重新声明

  1. var

    • 可以重新赋值和重新声明。

    • 例如:

var g = 7;
var g = 8;
console.log(g); // 8
  1. let

    • 可以重新赋值但不能重新声明。

    • 例如:

let h = 9;
h = 10;
// let h = 11; // 报错,Identifier 'h' has already been declared
console.log(h); // 10
  1. const

    • 既不能重新赋值,也不能重新声明。定义时必须初始化。

    • 例如:

const i = 12;
// i = 13; // 报错,Assignment to constant variable.
// const i = 14; // 报错,Identifier 'i' has already been declared

提升(Hoisting)

  1. var

    • 会被提升到其作用域的顶部,但不会初始化。

    • 例如:

console.log(j); // undefined
var j = 15;
  1. letconst

    • 也会被提升到作用域的顶部,但在初始化之前不能被访问(称为 “暂时性死区”)。

    • 例如:

console.log(k); // 报错,ReferenceError: Cannot access 'k' before initialization
let k = 16;

全局对象属性

  1. var

    • 在全局作用域下,用var声明的变量会成为全局对象的属性。例如,在浏览器环境中,var声明的变量会成为window对象的属性。

    • 例如:

var l = 17;
console.log(window.l); // 17
  1. letconst

    • 不会成为全局对象的属性。

    • 例如:

let m = 18;
const n = 19;
console.log(window.m); // undefined
console.log(window.n); // undefined

块级作用域与变量泄漏

  1. var

    • for循环中使用var,循环变量会在全局或函数作用域内共享,可能导致意外错误。

    • 例如:

for (var o = 0; o < 3; o++) {
  setTimeout(function() {
    console.log(o); // 最终会输出 3 三次,因为循环结束后 o 的值为 3
  }, 100);
}
  1. let

    • 使用let可以确保每次迭代都有一个新的绑定,解决了上述问题。

    • 例如:

for (let p = 0; p < 3; p++) {
  setTimeout(function() {
    console.log(p); // 分别输出 0、1、2,每次迭代都有新的绑定
  }, 100);
}

暂时性死区

  1. letconst

    • 暂时性死区是指在变量声明之前访问变量会导致引用错误。

    • 例如:

let q;
// console.log(q); // 报错,ReferenceError: Cannot access 'q' before initialization
q = 20;
console.log(q); // 20
  • 对于const也是同样的情况:

const r; // 报错,Missing initializer in const declaration

最佳实践

  1. const

    • 使用const声明那些不会改变的变量是个好习惯,可以强调代码的不可变性。

    • 例如:

const PI = 3.14159;
// PI = 3.14; // 报错,Assignment to constant variable.
  1. let

    • 只有在明确需要重新赋值的情况下使用let

    • 例如:

let count = 0;
for (let i = 0; i < 10; i++) {
  count++;
}
console.log(count); // 10
  1. 避免使用var

    • 在现代 JavaScript 编程中,几乎不会再用到var了,因为letconst能更好地处理作用域和提升问题。

letconst在 JavaScript 中提供了更安全、更清晰的变量定义方式,有助于避免一些常见的编程错误,提高代码的可读性和可维护性。