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

sumous_01

function a(){ var io = "io" mystart() function mystart(){ console.log(io); } } a() function a(){ var io = "io" mystart() } function mystart(){ console.log(io); } a() 请教一下: 1.为什么第一个可行,第二个不可行? 2.为什么第二个访问io变量的时候不会按照访问规则当前函数作用域下访问不到,到嵌套着它的函数作用域中去寻找? 3.两种写法的函数实际存储方式大概是怎样的?

阅读量:15

点赞量:0

问AI
🤣一个于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)