最近在补js基础。当初自学js的时候,总是感觉学的不扎实。只能说不去上手,再怎么死读书,也理解不了。积累了经验,然后自己去思考,这个时候再去看理论,就容易理解了。
感觉工作一年以来,确实学到了很多,但是过于专注于应用方面的知识,反倒基础上有些东西忘记了。虽说平时写代码多半没什么影响,但是基础扎实,才能让你知其所以然。搞技术的永远不能放弃对“知其所以然”的追求。
本篇文章小目标是当一个自己的笔记,免得过段时间又忘了。大目标就是写的详细一点,能让更多的人知其所以然
最精简的结论:
js作用域是静态作用域(词法作用域),在定义的时候就已经确定了。
而执行上下文,顾名思义是运行时的东西,要看是谁调用了谁。
todo 作用域和执行栈的画图解释,闭包,作用域的分类(全局script作用域,模块作用域)。js执行两阶段,活动对象等等
浅谈作用域和作用域链
当访问变量时,js引擎会首先在当前作用域找这个变量,找不到就沿着作用域链向上找,直到全局作用域。沿着作用域链能找到的变量,就可以访问。沿着作用域链找不到的,就不能访问。
js的作用域是静态作用域(也叫词法作用域),在定义的时候就已经被确定了,也就是说,要以代码被定义时的层级,作为作用域链。与之相对的是动态作用域,要以代码被调用的层级来作为作用域链(现代编程语言多数为静态作用域)
举个例子,
1 | let a = 1 |
这段js代码,打印出来的是2,因为fun2内部访问a的时候,沿着作用域链寻找,作用域链是按定义的层级来的,所以会找到fun1里面的a,而不是全剧最外面的a。
如果是动态作用域,那么会打印出来1,因为调用f的环境是在全局。
执行栈
js调用函数,是以栈的形式去实现的。有一个执行环境的栈,栈里面每一个元素都是一个执行上下文。至于什么是执行上下文,后面会详细讲解,可以简单理解为包含了函数执行相关信息,比如入参,和里面定义的变量等等。
最初的执行栈就只有一个元素,就是全局上下文。然后如果调用了别的函数,就会创建一个新的上下文,并且推入栈中,如果在函数内又调用了函数,就继续创建新的上下文并入栈。当函数执行完毕,这个函数的上下文就出栈。
这就是很基本的执行栈规则
很忙,有空再更新