深入理解ES6 001【学习笔记】

块级作用域绑定

之前的变量声明var无论在哪里声明的都被认为是作域顶部声明的,由于函数是一等公民,所以顺序一般是function 函数名()var 变量

块级声明

块级声明用于声明在指定块的作用域之外无法访问的变量。块级作用域存在于:

  • 函数内部
  • 块中(字符和{}之间的区域)

临时死区

javascript引擎在扫描代码发现变量声明时,要么将它们提升至作用域顶部,要么放到TDZ中。访问TDZ的变量会触发运行时错误。只有执行过变量声明后,变量才会从TDZ中移出,然后访问可正常访问。

if(condition){
  console.log(typeof value) // 引用错误
  let value = "blue";
}
// 以下的value并不在TDZ中
console.log(typeof value); // "undefined"
if(condition){
  let value="blue"
}

循环中的块作用域绑定

使用let 变量只存在于for循环中,一旦循环结束,无法访问这个变量

for(let i=0;i<10;i++){
  process(items[i]);
}
// i 在这里不可访问,抛出一个错误
console.log(i);

循环中的函数

var声明让开发者在循环中创建函数变得异常困难,因为变量到了循环之外仍能访问。

var funs = [];
for(var i=0;i<10;i++){
  funs.push(function(){
    console.log(i)
  })
}
funcs.forEach(function(func){
  func(); // 输出10次数字10
})

为了解决这个问题,开发者们在循环中使用立即调用函数表达式,以强制生成计数变量的副本。IIFE表达式为接受的每一个变量i都创建一个副本并存储为变量value。这个变量的值就是相应迭代创建的函数所使用的值,因此调用每个函数

var funs = [];
for(var i=0;i<10;i++){
  funs.push((function(value){
    return function(){
      console.log(i)
    }
  })(i))
}
funcs.forEach(function(func){
  func(); // 输出0,1,2...
})

循环中的let声明

let声明模仿上述所做的一切来简化循环过程,每次迭代循环都分创建一个新变量,并以之前迭代中同名变量的值将其初始化。也适合于for-in for-of for-each

var funs = [];
for(let i=0;i<10;i++){
  funs.push(function(){
    console.log(i)
  })
}
funcs.forEach(function(func){
  func(); // 输出0,1,2...
})

let声明在循环内的行为是标准中专门定义的,它不一定与let的不提升特性相关,理解这一点至关重要。事实上,早期let实现中不包含这一行为。是后来加入的。

循环中使用const

for(const i=0;i<10;i++)会报错,因为i++时试图改变常量i的值。而在for-infor-of中因为没有去试图改原i值的操作。而是新创建了一个变量。所以执行会跟使用let声明一样

全局作用域绑定

letconstvar的另外一区别是它们在全局作用域中的行为。当var被用于全局作用域时,它会创建一个新的全局变量作为全局对象的属性。这意味着var很有可能会无意中覆盖一个已经存在的全局变量。而使用letconst不能覆盖全局变量,而只能遮蔽它。so

let RegExp = 'Hello world'
console.log(window.RegExp === RegExp)

主题测试文章,只做测试使用。发布者:Walker,转转请注明出处:https://joyjs.cn/archives/4308

(0)
Walker的头像Walker
上一篇 2025年3月8日 10:59
下一篇 2025年3月27日 15:01

相关推荐

  • Go工程师体系课 protoc-gen-validate【学习笔记】

    protoc-gen-validate 简介与使用指南 ✅ 什么是 protoc-gen-validate protoc-gen-validate(简称 PGV)是一个 Protocol Buffers 插件,用于在生成的 Go 代码中添加结构体字段的验证逻辑。 它通过在 .proto 文件中添加 validate 规则,自动为每个字段生成验证代码,避免你手…

    个人 2025年4月27日
    1.0K00
  • 深入理解ES6 006【学习笔记】

    Symbol和Symbol属性 第6种原始数据类型:Symbol。私有名称原本是为了让开发者们创建非字符串属性名称而设计的,但是一般的技术无法检测这些属性的私有名称 创建Symbol let firstName = Symbol(); let person = {} person[firstName] = "Nicholas"; cons…

    个人 2025年3月8日
    1.0K00
  • 测试专题

    个人 2025年2月7日
    1.1K00
  • 无畏前行,拳释力量 🥊💪

    拼搏,是一种态度 生活就像一场比赛,没有捷径可走,只有不断训练、突破、超越,才能站上属于自己的舞台。这不仅是一种对抗,更是一种自我的觉醒——敢于迎战,敢于挑战,敢于成为更强的自己。 运动中的拼搏精神 无论是拳击、跑步,还是力量训练,每一次出拳、每一次挥汗、每一次咬牙坚持,都是对身体与心灵的磨炼。拼搏不是单纯的对抗,而是一种态度——面对挑战,不退缩;面对失败,…

    个人 2025年2月26日
    1.0K00
  • 深入理解ES6 012【学习笔记】

    代理(Proxy)和反射(Reflection)API 代理是一种可以拦截并改变底层javascript引擎操作的包装器,在新语言中通过它暴露内部运作对象,从而让开发者可以创建内建的对象。 代理陷阱 覆写的特性 默认特性 get 读取一个属性值 Reflect.get() set 写入一个属性值 Reflect.set() has in操作符 Reflect…

    个人 2025年3月8日
    92600

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信
欢迎🌹 Coding never stops, keep learning! 💡💻 光临🌹