当前位置: 首页 > news >正文

《JavaScript 核心原理解析》学习笔记 Day 2 未声明变量 变量声明与词法声明

        前置知识:变量提升暂时性死区。此处略。

        JavaScript 中有六种声明用语句:let、const、var、function、class、import。其声明处理方式如下:

        变量声明(varDelcs)

                1. var 变量声明。在创建变量名(varName in varDecls)后,会绑定一个 undefined 值作为初始化,因此 var 声明的标识符未赋值时也可访问;

                2. function 函数声明。其名称声明规则同 var。

        词法声明(lexicalDecls)

                1. let 变量声明。在创建词法名字(lexicalNames)后,不会进行值绑定,因此未赋值时 let 或 const 声明的标识符存在暂时性死区,访问即会报错;

                2. const 常量声明。声明后的常量不可修改,也存在暂时性死区;

                3. class 类声明。类的内部为严格模式,其名称声明规则同 let;

                4. import 导入声明。其名称声明规则同 const。

        综上,所有的声明本质上只有三种处理模式:var 变量声明、let 变量声明和 const 常量声明

        而向未声明变量赋值时,JavaScript 会在全局范围内创建它,但其表现与 var 声明的变量不同。另外 eval() 中的var 声明效果也有所不同。其原因在于虽然它们都被创建为全局对象 global 的属性,但所有在静态语法分析期或在 eval() 中使用 var 声明的变量名都会被置于一个全局对象外维护的变量名列表(varNames 列表)中,在这个变量名列表中的变量是“直接声明的变量”,不能使用 delete 删除。所以 var 声明的变量不能用 delete 删除,但被赋值的未声明变量可用 delete 删除。然而在 eval() 中使用 var 声明的变量名又可以从此变量名列表中被移除,因此 eval() 中使用 var 声明的变量可以通过 delete 删除。具体区别见如下代码:

var a=100
b=200
eval('var c=300')
// a、b、c 均为全局对象 global 的属性,但只有非 eval() 中通过 var 声明的变量是不可配置的
Object.getOwnPropertyDescriptor(global, 'a'); // {value: 100, writable: true, enumerable: true, configurable: false}
Object.getOwnPropertyDescriptor(global, 'b'); // {value: 200, writable: true, enumerable: true, configurable: true}
Object.getOwnPropertyDescriptor(global, 'c') // {value: 300, writable: true, enumerable: true, configurable: true}
// a 是不可以通过 delete 删除,而 b、c 可被删除
delete a // false
delete b // true
delete b // true
a // 100
b // ReferenceError: b is not defined
c // ReferenceError: c is not defined

        另外词法名字列表(lexicalNames 列表)中的项都是不可移除的,也就无法通过 delete 删除

        最后再来看 var x=y=100 这行代码,即 var x=(y=100)。右侧是表达式 y=100,其对未声明变量 y 进行了赋值,也就在全局创建了一个可用 delete 删除的变量 y。而表达式 y=100 的执行结果 100 又绑定给了 var 声明的不可通过 delete 删除的变量 x。 另外注意:声明语句中无赋值。赋值发生在两个表达式之间,而声明语句 var x 中的 x 是一个标识符,而非表达式。具体区别见如下代码:

// x 是 var 声明的变量,y 是未声明变量
var x = y = 100
// x 不可配置,y 可配置
Object.getOwnPropertyDescriptor(global, 'x') // {value: 100, writable: true, enumerable: true, configurable: false}
Object.getOwnPropertyDescriptor(global, 'y') // {value: 100, writable: true, enumerable: true, configurable: true}
// x 无法通过 delete 删除,而 y 可被 delete 删除
delete x // false
delete y // true
x // 100
y // y is not defined

相关文章:

  • 怎么用 java做网站/全媒体运营师培训费用
  • 同程网站建设分析/著名的营销成功的案例
  • 集团门户网站建设不足/网站模板之家
  • wordpress响应式按钮/找回今日头条
  • 国外有个专门做病毒营销网站/精准推广
  • wordpress分页上一页/上海网站建设推广服务
  • Python和MySQL对比(5):用Pandas实现MySQL窗口函数的效果
  • 【Hadoop】HDFS的常见shell操作
  • 每日一题-力扣(leetcode)2368. 受限条件下可到达节点的数目
  • MongoDB 中(BsonDocument Document Bson)关系详解
  • 机器视觉 · 工业光源
  • Linux多线程 线程概念 | 线程VS进程 | 线程控制【万字精讲】
  • 亚商投资顾问 早餐FM/0118加强火电行业监测能力建设试点
  • NodeJS安装和配置
  • Acwing---1237.螺旋折线
  • 23种设计模式(八)——工厂方法模式【对象创建】
  • SNARK原理示例
  • 一篇文章带你熟悉Ajax