JavaScript简明教程-let和const

439 阅读2分钟

基本概念

let

  • let声明的变量只在let所在的代码块内有效
// for循环,设置循环变量是一个父作用域,循环体内又是一个作用域
for(let i = 0; i < 10; i++) {
	let i = 'abc';
	console.log(i); // abc
}
console.log(i); // 报错
  • let声明不存在变量提升
  • 暂时性死区(let变量声明前,该变量都是不可使用)
  • let不允许相同作用域内,重复声明同一变量

const

  • 声明只读常量,一旦声明,值就不能改变
  • 只在声明的块级作用域内有效
  • const声明不存在变量提升
  • 暂时性死区
  • 相同作用域内不可重复声明
  • 不要使用const定义对象,因为此时虽然定义的对象,一样可以修改
const foo = {};
foo.info = 'info';

const的本质

const 只能保证变量指向的那个内存地址,所保存的值不可变动

简单类型的数据(数值、字符串、布尔值),变量指向的内存地址直接保存相关数据

复合数据类型(主要是对象和数据),变量指向的内存地址,保存的是实际数据的指针,这个指针只是固定的指向另外一个地址,至于这个指向的地址对应的数据结构是不是可变的,就无法控制。

所以使用 const 定义的简单数据类型可以理解为常量,如果修改会报错,但是如果使用const定义复合数据类型,修改这个对象的值,一样是可以的。

声明变量的方法

  • var
  • function
  • let
  • const
  • import
  • class

var 是 functuon scope,声明的变量,只有处在于某个函数中才会变成局部变量,否则就是全局变量,let、const 是 block scope ,声明的变量,只要存在于某个大括号内就是局部变量,大括号外无法访问

顶层对象、全局变量

顶层对象,在浏览器环境指的是 window 对象,在 Node 指的是 global 对象,ES5之中,顶层对象和全局对象是等价

ES6后,var、function声明的全局变量,依然会加挂到顶层对象上,但let、const、class声明的全局变量,不再属于顶层对象(也就是不能直接通过window对象的形式访问)

块级作用域

块级作用域内避免使用函数声明,可以使用函数表达式

// 下面情况下直接使用会报错
function f() { console.log('I am outside!'); }

(function () {
  if (false) {
    // 重复声明一次函数f
    function f() { console.log('I am inside!'); }
  }

  f();
}());
// Uncaught TypeError: f is not a function
...
// 但是如果使用函数表达式就不会
function f() { console.log('I am outside!'); }

(function () {
  if (false) {
    // 重复声明一次函数f
    let f = function () { console.log('I am inside!'); }
  }

  f();
}());
// I am outside! 这是一个符合预期的结果