1.let和const关键字

本文详细介绍了JavaScript中let和const的特性:let创建块级作用域,避免变量提升和临时性死区;const声明不可变常量,要求初始化且不能重新赋值。文中通过实例展示了let如何解决循环中的作用域问题,以及const在对象引用上的特殊情况。同时,文章探讨了let和const在声明重复、变量提升和作用域方面的差异,帮助读者深入理解这两者在实际编程中的应用。
摘要由CSDN通过智能技术生成

1. let


1.1 let声明的变量会创建自己的块级作用域

不多bb,直接上代码:

{
  let a = 10
  var b = 1
}

a // ReferenceError: a is not defined.
b // 1
function f1() {
  let n = 5
  if (true) {
    let n = 10
  }
  console.log(n) // 5
}

function f1() {
  let n = 5
  if (true) n = 10
  console.log(n) // 10
}

for循环很适合使用let

var a = []
for (let i = 0; i < 10; i++) {
  // let i = 6
  a[i] = function () {
    console.log(i)
  }
}
a[6]() // 6

var a = []
for (var i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i)
  }
}
a[6]() // 10

分析:

// let声明的变量可以创建自己的作用域,故i得以保存
a[i]Context = {  // a[i]函数定义时的上下文
  AO:{
    arguments:{
      length:0
    },
    i: 0 // 0 ~ 10,let可以创建自己的作用域,每轮循环都会在AO里添加i变量
  }
}
// 而 var声明的变量无自己的作用域,获取的是全局变量
gContext = {
  VO:{
    a[0]:function(){console.log(i)},// a[1] ~ a[9] 
    i: 10
  }
}
a[i]Context = {
  AO: {
    arguments:{
      length:0
    }
  }
}

1.2 let不存在变量提升

// var 的情况
console.log(a) // 输出undefined
var a = 2
a
// let 的情况
console.log(a) // 报错ReferenceError
let a = 2

1.3 let声明的变量会存在暂时性死区

let声明的变量会绑定当前的作用域,不再受外部的影响,且在当前区域锁死let声明之前的变量访问

var a = 7
if(true){
  a = 8 // ReferenceError,这是因为a只能用内部的,外部的不行,然后内部在声明前就访问会报错
  let a// 暂时性死区结束
  a = 9
  alert(a) // 9
}

当然,也有隐形的死区

function fn(x = y, y = 2) {
  return [x, y]
}
fn() // 报错,这是因为y未声明就试图用其给x赋值

// 下面这样就不会报错
function fn(x = 2, y = x){
    return [x, y]
}
fn() // [2, 2]

1.4 let不允许重复声明

不多bb,直接上代码:

// 报错
function fn() {
  let a = 10
  var a = 1
}

// 报错
function fn() {
  let a = 10
  let a = 1
}

// 隐形重复声明,通过函数参数 
function fn(arg) {
  let arg
}
fn() // 报错

function fn(arg) {
  {
    let arg
  }
}
fn() // 不报错,这是因为在arg声明在嵌套的语句块里

2. const


const与let类似,只不过更加严格:

  • 声明的变量不能改变(常量)
  • 声明时必须赋值,不能后面再赋值

在本质上,const保证的是指针不改变,但是改变指针所指的对象的属性是可以的喔~

如果要定义一个"常量对象",那么要使用Object.freeze(obj),效果相当于将对象的每个属性const

const obj = Object.freeze({ name: 'jack' }) 

那么问题又来了,如果对象的属性又是一个对象咧?我不改它的指针,我可以改它的属性啊!哈哈,那么彻底冻结吧~

function constantize(obj){
  Object.freeze(obj) // 冻死外部
  Object.keys(obj).forEach(key =>{ // 排查内部漏网之鱼
    if(typeof obj[key] === 'object'){
      // 你这个属性是一个对象是吧?老子套娃冻死你!
      constantize(obj[key])
    }
  })
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值