[ES6]变量与常量

[ES6]变量与常量

  • 变量 let & var 关键字
    • 变量表明生效范围案例
    • 变量提升
      • 什么是变量提升
      • 关键字与提升
  • 常量关键字 const
  • 暂时性死区
  • 使用问题

ES6 新增了变量 let 与常量 const,用于替代 var

  • let
    • 生效范围:代码块内有效
    • 声明重复性:不可重复声明
    • 变量提升:不存在
  • var
    • 生效范围:全局范围有效
    • 声明重复性:可重复声明
    • 变量提升:存在
  • const
    • 生效范围:代码块内有效
    • 声明重复性:不可重复声明
    • 简单类型,只读常量,声明时赋值并不可修改;复杂类型,是指指针常量

变量 let & var 关键字

之所以出现 let 关键字,就是因为 var 存在一些缺陷,导致了一些报错问题,因此使用 let 与 const 关键字替代 var

let 是用于定义变量,值可以修改

变量表明生效范围案例

这是一个变量表明生效范围案例,非常清晰又明确的展示出了代码块有效与全局有效的区别!!!!

for (var i = 0; i < 10; i++) {
  setTimeout(function () {
    console.log(i);
  });
}
// 输出十个 10
for (let j = 0; j < 10; j++) {
  setTimeout(function () {
    console.log(j);
  });
}
// 输出 0123456789

变量 i 是用 var 声明的,在全局范围内有效,所以全局中只有一个变量 i, 每次循环时,setTimeout 里面的 i 指的是全局变量 i ,而循环里的十个 setTimeout 是在循环结束后才执行,所以此时的 i 都是 10。

变量 j 是用 let 声明的,当前的 j 只在本轮循环中有效,每次循环的 j 其实都是一个新的变量,所以 setTimeout 定时器里面的 j 其实是不同的变量,即最后输出 12345。(若每次循环的变量 j 都是重新声明的,如何知道前一个循环的值?这是因为 JavaScript 引擎内部会记住前一个循环的值)。

变量提升

什么是变量提升

就是当我们写代码的时,正常情况我们理应声明变量先于使用变量,然后各种原因导致了使用变量先于声明变量的情况,但是程序并不报未定义错误,对于这种未正常声明在先却能正常使用情况我们称之为变量提升

使用变量包括赋值的情况

关键字与提升

var 存在变量提升,并且函数提升大于变量提升
let 声明的变量只在声明的代码块中有效,并且不存在变量提升,否则直接报错

因为 var 是全局范围内有效,所以编译器会将声明放置编译后的文件头部,所以出现了变量提升

常量关键字 const

const 是用于定义常量的

const 在声明初始化之后不允许改变!!!const 其实保证的不是变量的值不变,而是保证变量指向的内存地址所保存的数据不允许改动。

但是,简单类型和复合类型保存值的方式是不同的。

简单类型(数值 number、字符串 string 、布尔值 boolean),值就保存在变量指向的内存地址,因此 const 声明的简单类型变量等同于常量。

而复杂类型(对象 object,数组 array,函数 function),变量指向的内存地址其实是保存了一个指向实际数据的指针,所以 const 只能保证指针是固定的,至于指针指向的数据结构变不变就无法控制了,所以使用 const 声明复杂类型对象时要慎重。因此实际上是可以修改 const 的复杂类型的属性值,但是不能够是指针指向的内存地址发生变化,例如:

const foo = {};
foo.number = 1; //允许
foo = {}; //指向新的对象 报错

暂时性死区

在代码块内,使用 let 命令声明变量之前,该变量都是不可用的,在语法上,称为该变量"暂时性死区"(temporal dead zone,简称 TDZ)

if (true) {
  // TDZ开始
  tmp = "abc"; // ReferenceError
  console.log(tmp); // ReferenceError

  let tmp; // TDZ结束
  console.log(tmp); // undefined

  tmp = 123;
  console.log(tmp); // 123
}

从没有声明使用变量开始,到声明之间的区间都是 TDZ。

使用问题

var tmp = 123;
if (true) {
  tmp = "fff"; // ReferenceError
  let tmp; //绑定块级作用域
}

var 可以声明同名的变量或方法

若是同名的 var 与 let 变量均存在,只要绑定过 let,语法规则都按照 let

let 变量一定要在声明之后使用,否则就报错

在同一代码块中 let 不可以重复声明,但是不同层级是可以的,并且相互之间互不影响

let 的说明非常明确

你可能感兴趣的:(es6,javascript,前端)