Open XingGuoZM opened 1 year ago
js引擎编译过程是将js代码转化成机器能识别的字节码,js代码->tokens->ast->字节码
js代码编译过程中确定(狭义理解为函数定义时创建的),是变量访问规则,变量如何存储和访问的,换句话说即变量的作用和影响的范围。在浏览器上断点我们可以看到有4中作用域(Global、Local、Closure、Script)
for(var i = 0; i < 5; i++) {
setTimeout(() => {
console.log(i);
},1000);
}
js代码执行过程中,变量的查找规则
构造函数和实例对象链接的纽带.
静态作用域和动态作用域.
编译时确定和执行时确定.
js代码执行过程中所处的环境,通过创建一个上下文对象来描述这个环境。执行过程中(函数调用时)js引擎会创建一个上下文对象,把this指向该对象,同时会创建词法环境和变量环境。分为上下文创建阶段和执行阶段。
上下文创建规则:方法调用,当前上下文就是该对象,函数调用,当前上下文就是全局对象(严格模式是undefined,非严格模式window).
this指向当前得执行上下文对象,在函数/方法执行时,会创建执行上下文对象,this指向该上下文对象(函数运行时的环境)
用来存储代码运行时所创建的所有执行上下文。js引擎会从执行栈顶取任务进行执行,执行完成之后进行销毁(作用域、上下文)
作用域基于函数,执行上下文基于对象
在创建执行上下文的时候,js引擎会扫描找出所有变量和函数声明,var创建的变量会有赋一个初始值undefined,而let/const创建的变量
在执行上下文创建阶段,var创建的变量会赋值undefined(存在作用域内),而let/const创建的阶段为为初始化(不存在作用域内),等到执行阶段可以访问到var创建的变量初始值;而let/const创建的变量还未加入到作用域内,因此访问不到该值,只有等到执行到对应定义语句时才加入到作用域上,从访问变量到定义变量这段称之为暂时性死区。
作用域链的特殊情况,函数运行完毕之后,与之相关的作用域也会被销毁,如果父函数已经执行完成了,但是子函数还未执行,并且引用了父函数的变量。这时候与之相关的变量就会打包存入内存中而不被销毁,等到子函数执行的时候还能访问到变量。闭包即变量在当前执行上下文被销毁之际仍然被其他变量所引用,因此将变量进行打包处理存在内存,以便能随时访问到。
var name = "jay";
var person = {
name: "kang",
pro: {
name: "Michael",
getName: function() {
return this.name;
}
}
};
console.log(person.pro.getName());//
var pepole = person.pro.getName;
console.log(pepole());//
参考
理解编译过程? 什么是静态作用域?什么是动态作用域? 什么是作用域?什么是作用域链? 什么是执行栈(call stack)?什么是执行上下文? 怎么创建执行上下文?什么时候销毁上下文? 怎么理解css中格式上下文的? 什么是BFC? 你是怎么理解上下文的? new过程中做了啥? 什么是原型?什么是原型链? 如何理解面向对象(OOP)?OOP有什么作用? class 、prototype 到底和 OOP 有什么关系? 基于类(class-based) 和基于原型(prototype-based) typescript的出现是为了解决什么问题? 执行上下文和执行栈、作用域和作用域链、原型和原型链有什么关联? 什么是变量提升和函数提升? 什么是暂时性死区? 什么是闭包?作用域和闭包关系?
为什么会有闭包?什么时候创建的 [[scopes]] 属性是什么 闭包保存什么内容?闭包存储在哪 为什么 eval 性能不好?eval 什么情况下会创建闭包? 作用域的本质是什么?闭包和作用域的关系是什么? this指向问题?函数、方法、call/bind、 函数栈溢出和尾递归归优化?