- 浏览器运行机制
- 变量提升机制
- 私有变量提升步骤
- 全局对象 GO 和全局变量对象 VO的区别
- 带var和不带var的区别
- 系统输出顺序
- 变量提升在条件判断下的处理
- 防止函数的变量提升
浏览器运行机制
- 为了能够让代码执行,浏览器首先会形成一个
执行环境栈
ECStack(Execution Context Stack) - 有了栈内存代码就可以自上而下的执行
- 开始执行全局下的代码,形成一个
全局执行上下文
EC(GLOBAL 简写 GO ) - 对应代码会在自己所属的执行上下文中执行,而环境有一个存放变量的地方
VO
(Virtual Object) 全局变量对象AO
(Activeion Object) 私有变量对象
变量提升机制
变量声明
提升函数声明定义整体
提升
console.log(a) var a
console.log(func) ===> function func (){
var a = 10 var b
function func () { console.log(b)//undefined
console.log(b) b = 20
var b = 20 console.log(b)//20
console.log(b) }
} console.log(a)//undefined
func() console.log(func)//f func(){ ... }
console.log(a) a = 10
func()
cosnole.log(a)//f func(){...}
===============================================================
GO:{
a: undefined -> 10
func:f (){...}
}
AO:{
b: undefined -> 20
}
私有变量提升步骤
- 创建AO对象(私有执行期上下文)
- 找形参和变量声明,将变量和形参作为AO属性名,值为 undefined
- 将实参与形参统一
- 函数声明定义整体提升
function func (b) {
console.log(b);//3
console.log(test);//f test(){...}
var b = 20;
console.log(b);//20
function test (){}
}
func(3)
===========================
AO:{
b: undefined -> 3 -> 20
test: f(){...}
}
例题链接
全局对象 GO 和全局变量对象 VO的区别
全局对象GO: ==》 对象
浏览器默认自带很多JS
调取使用的内置API
,这些属性方法都在GO
中存储
浏览器端 GO === window
node端 GO === global
通用 globalThis
全局变量对象VO: ==》栈内存
当全局代码执行过程中,声明的变量都存储在VO
中
带var和不带var的区别
全局执行上下文中
带var:基于var创建变量,会给VO
和GO
中各存储一份
不带var:不创建变量,而是设置GO
属性
全局执行上下文中
带var:基于var创建变量,给AO
中存储
不带var:
- 沿着
作用域链
(scoped-chain)往上走,查看是谁的变量 - 如果全局也没找到,则
设置GO属性
(window)
系统输出顺序
- 首先是否为全局变量
GO
,是则输出全局变量的值 - 是否为全局对象的属性
VO
,是则输出全局对象的属性 - 报错 a is not defined
var a = 1
window.a = 2; // 会把VO中变量a也改掉
console.log(a); // 2
防止函数的变量提升
函数表达式
,提升在函数执行时的不严谨性
var a = function (){}
变量提升在条件判断下的处理
禁止在判断或循环中声明函数
console.log(a)//undefined
if(true){
a=3
console.log(a)//3
function a(){}
console.log(a)//3
}
console.log(a)//3