Day 11 JavaScript var vs let (1)

这两天会介绍到 JS 内 var 与 let 的差异,今天跟明天分别介绍两点。

JS 的 var 以及 let 主要在以下四点有差异:

  1. 作用范围 Scope
  2. 变数提升 Hoisting
  3. 执行环境 Execution Context
  4. 宣告 declaration

作用范围 Scope:

在区域内的作用范围不同。

  • var : 以 function( ) 为作用范围
  • let : 以 block { } 为作用范围

简单来说,function 可以关住 var 及 let (因为 function 也有使用到 { } ),而 block 只能关住 let。

当 var 的作用范围在 block { } 时,var 无法被关住,会溢出到外面变成全域变数,JS 会自动在全域环境下宣告一个 i 变数出来。

范例

for (var i = 0; i < 3; i++) {
    console.log(i)             
//  印出 0, 1, 2
}

console.log(i)                 
//  印出 3
//  因为 { } 无法关住 var ,造成 i 溢出。
//  在上个回圈的 i 递增到3就停止了,JS 会在全域环境下生出 var i = 3。
//  导致最後外层的 console.log 印出3
                               
for (let j = 0; j < 3; j++) {
    console.log(j)             
//  印出 0, 1, 2
}

console.log(j)                 
//  印出 "error" ReferenceError: j is not defined
//  因为 let 被 { } 关住,所以 j 不会溢出。
//  外层没有 j 变数,导致喷错。

变数提升 Hoisting:

JS里才特有的东西,若用 var 将变数定义在函式下方,执行结果不会跑出 not define,而是跑出undefined,是因为 JS 把变数提升移动到函式上方(大众说法),但其实里面的程序码并不会上下跑动。

JS执行程序时会经历两段时期:

  1. 建立期:JS 会先分配记忆体给宣告的变数及函式,其中函式又会比变数优先被宣告。

    在建立期会做两件事情(依照 1A、1B 的顺序):
    1A:注册名称 = 建立罐子,JS 会宣告变数,但不会赋值给变数。
    1B:初始化 = 给他空气,因为没有值的关系,这个变数的值会是 undefined。

  2. 执行期:执行程序码。

    在执行期也会做两件事情(依照程序码由上至下的顺序):
    2A:把宣告变数里的值指定给变数。
    2B:执行函式。

  • var 有变数提升,在 1B 初始化的时期,变数会被赋予 undefined,即使把宣告写在後面也能执行,不会出错。
  • let 有变数提升,但是 let 要等到 2A 赋值之後,才能进行 1B 的初始化,在那之前会被 TDZ 盖住,导致 JS 无法读取他,最後会出错。

var

console.log(a)
var a = 1
//  印出 undefined

//  程序码由上开始往下读取
//  1.跳过 console.log
//  2.执行 1A  var a
//  3.执行 1B  var a = undefined
//  4.回到 console.log ,执行 2B  undefined => 被印出
//  5.执行 2A  a = 1

let

  • 用 var 在宣告时,变数会变成全域变数。
  • 用 let 宣告时,变数会变成区域变数,JS 在 1A 时会用一个 TDZ (Temporal Dead Zone 暂时死区) 把变数盖住,当给予值後才能把盖子打开。
console.log(a)
let a = 1
//  印出 Cannot access 'a' before initialization

//  程序码由上开始往下读取
//  1.跳过 console.log
//  2.执行 1A  let a 并且给他一个TDZ
//  3.执行 1B  变数a因为被 TDZ 盖住,所以无法执行初始化
//  4.回到 console.log 执行 2B ,因为a被盖住无法进行 1B 的初始化
//  ReferenceError: Cannot access 'a' before initialization => 被印出

参考:
[1]What's the difference between using "let" and "var"?


<<:  [Day12]加密方式

>>:  【DAY 12】简单化、视觉化组织团队工作 - Planner

Day11 - this&Object Prototypes Ch3 Objects - Contents - Existence

作者说明了两种确认 object 特定 property 是否存在的方式 in operator:p...

#23 数据中中的特徵相关性(2)

相关距离(Correlation Distance) 相关距离定义: python实现相关系数 im...

Day 03:Android 开发工具

前言 在开始写 Android 之前,想先介绍如何提升写 code 的速度, 如果从现在开始习惯,并...

[Java Day24] 6.1. 继承

教材网址 https://coding104.blogspot.com/2021/06/java-i...

CSS微动画 - Loading来了!终於要出款文字版本的了!

Q: 说好的文字Loading呢? A: 客倌这里上菜罗~ 前几篇的Loading都是以图案循环为...