ECMA-262中的var/let/const
在ECMA-262中,ES6之后对代码的执行流程描述改成了另外的一些词汇
基本的执行思路是不变的
比如:ECS(执行上下文栈)和EC(执行上下文)
在代码被解析之前,执行上下文栈中会创建一个全局的执行上下文,但是其中包含的是词法环境(lexicalEnviroment)和变量环境(variableEnviroment),同时会在堆内存中生成全局的词法环境,而词法环境又包含环境记录(Enviroment Record)和外部词法环境(outer),全局的词法环境的outer为null,环境记录会指向对应的环境记录的对象,会有自己的属性和方法。
全局的环境记录!=window, 全局的环境记录是由两个环境记录合成的
环境记录主要包含声明式环境记录和对象环境记录。
- 声明式环境记录:声明性环境记录用于定义ECMAScript语言语法元素的效果,如函数声明、变量声明和直接将标识符绑定与ECMAScript语言值关联起来的Catch子句。(全局的环境记录中-let/const)
- 对象式环境记录:对象环境记录用于定义ECMAScript元素的效果,例如WithStatement,它将标识符绑定与某些对象的属性关联起来。(全局的环境记录中-window)
var和let/const的区别
var是被存放在变量环境(variableEnvironment)中,当代码被解析的时候就创建出来了,可以在赋值执行前被访问到,值为undefined。
1 | function foo() { |
let/const是被存放在词法环境中(lexicalEnviroment)中,当代码被解析的时候也被创建出来了,但是在被赋值之前是不能被访问的,如果访问会报错。
1 | function foo() {// 从这个大括号开始 |
let/const的基本使用
let和var区别不大,声明一个变量可以被赋值(早期语言的设计缺陷)。
const声明一个常量,如果赋值一个对象的,可以修改对象里面的内容。
let和const不允许重复声明。var是可以的,后面的会把前面的覆盖。
- var定义的变量会被添加到window上
- let/const不会被添加到window上
let/const有作用域提升嘛?
作用域提升:在声明变量的作用域中,如果这个变量可以在声明之前被访问,那么我们可以称之为作用域提升。
但是在这里let和const是有被提前创建出来,但是不能访问,所以我认为是let/const不具备作用域提升。
暂时性死区(TDZ,temporal dead zone)
暂时性死区和代码的定义位置无关,和代码的执行顺序有关。
1 | function foo() { |
这里是先创建foo(),定义message,然后给message赋值,最后执行foo(),所以在foo()的函数体中可以访问到message。
tips
早期JS(ES6之前)只有全局作用域和函数作用域。
模板字符串
1 | const name = "beichen" |
模板字符串可以通过``来调用函数,并且传入参数,以及我们自己想添加的东西
args打印的东西分两类,一个是通过${}分割的字符串,会存入到一个数组中[‘this is name ‘, ‘, ???’],第二个就是”beichen”。
args = [["this is name ", ", ???"], "beichen"]
展开语法
可迭代对象: 数组/字符串/arguments
对象默认不是可迭代对象。
Symbol
1 | // description描述 |
set/map
set基本使用
1 | const names = ['abc', 'abd', 'nba', 'cba'] |
set常用属性: size
set常用方法:
- add(value)
- delete(value)
- has(value)
- clear()
- forEach()
- for-of
map基本使用: 以对象作为key来储存
1 | const obj1 = { name: "beichen" } |
map常用属性: size
map常用方法:
- set(key)
- get(key)
- has(key)
- delete(key)
- clear()
- forEach(item => console.log(item))
- for-of