函数写在函数里面和函数外面有什么区别?-灵析社区

兰豆儿

🤣一个于JS作用域的基础问题 从作者的提问可以了解到的是,作者对于JS作用域没有一个清晰的概念。下面先交代一下JS的作用域是什么吧! ## 作用域 Java Script引擎在执行JavaScript代码时,需要用到编译器、执行引擎和作用域。 * 编译器:语法分析、代码生成等功能。 * 执行引擎:从头到尾负责整个程序的编译及执行过程。 * **作用域:负责收集并维护所有标识符组成的一系列查询,并确定当前执行代码对这些标识符的访问权限。** ### 动态作用域VS静态作用域 在编程语言中可以将作用域分为**动态作用域** 和**静态作用域** * 动态作用域:在**运行时** 确定作用域关系 * 静态作用域:在**编译时** 确定作用域关系 JS的作用域属于静态作用域,简单理解就是,**作用域关系是在代码编写的时候就已经确定了的** ,无论在哪里调用和执行都不会变。 ### JS中的作用域 首先,在js中的作用域分为全局作用域、函数作用域和块级作用域。在之前js只存在全局作用域和函数作用域,ES6之后引入了块级作用域。而块级作用域只适用于`const`和`let`声明的变量,所以这里我们不需要考虑块级作用域。 // 这里是全局作用域 function test() { // 这里是函数作用域 } 在`js`中变量的查找是从当前的函数作用域开始向上查找的,也就是说如果在`test`中使用变量`a`,那么会先在`test`的函数作用域查找,如果在`test`中存在变量`a`则停止查找。 ## 回答问题 ### 问题一 > 为什么第一个可行,第二个不可行? function a(){ var io = "io" mystart() function mystart(){ console.log(io); } } a() 这里涉及到了一个全局作用域和两个函数作用域,当执行`a()`时,函数`a`中声明了函数`mystart`,也就是说`a`的函数作用域是`mystart`的父级作用域。 ![image.png](https://wmprod.oss-cn-shanghai.aliyuncs.com/images/20241126/38744b1172f8075c95f6af4d7da54f78.png) 当执行`mystart`时,`console.log(io)`会在当前的`mystart`作用域中查找`io`变量,发现`mystart`中不存在`io`变量后,会向`mystart`的父级作用域(`a`函数作用域)查找,此时在`a`函数作用域中顺利找到`io`变量。于是顺利打印出`"io"`。 但是对于下面的代码: function a(){ var io = "io" mystart() } function mystart(){ console.log(io); } a() 这段代码与上面的不同之处在于,`mystart`的父级作用域不再是函数`a`,而是全局作用域。 ![image.png](https://wmprod.oss-cn-shanghai.aliyuncs.com/images/20241126/396858b2c8c63eb94692725884aa4640.png) 这时候在执行`mystart`时,查找`io`变量就不会再去`a`函数作用域中查找了,由于全局作用域中没有`io`变量。那么`console.log(io)`就会查找不到`io`变量,那么抛出`ReferenceError`异常。 ### 问题二 > 为什么第二个访问io变量的时候不会按照访问规则当前函数作用域下访问不到,到嵌套着它的函数作用域中去寻找? 之所以有这样的疑惑,是因为错误的将JS的作用域机制理解成了动态作用域导致的。 然而**JS采用的是静态作用域规则,也就是说JS的作用域是在编写代码时就确定的** 。将`mystart`写在全局作用域下,**那么`mystart`的父级作用域就是全局作用域**,而不是`mystart()`调用时所在的作用域(`a`函数作用域)。 所以题主理解错了JS的作用域,才会奇怪为什么不会去嵌套作用域中寻找! ### 问题三 > 两种写法的函数实际存储方式大概是怎样的? 参考这两个图 ![image.png](https://wmprod.oss-cn-shanghai.aliyuncs.com/images/20241126/38744b1172f8075c95f6af4d7da54f78.png) ![image.png](https://wmprod.oss-cn-shanghai.aliyuncs.com/images/20241126/396858b2c8c63eb94692725884aa4640.png)

阅读量:1

点赞量:0

问AI