作用域JavaScript中的作用域分为全局作用域、函数作用域和块作用域。全局范围在全局范围内声明的变量可以从任何地方访问。varmessge='Hello'functionsay(){console.log(message)}say();//在Hello函数范围内声明的变量只能在函数内访问。功能说(){varmessge='你好';控制台日志(消息);}说();//Helloconsole.log(问候语);//ReferenceError:messgeisnotdefinedblockscopeES6引入了let和const关键字,它们声明的变量只能在该代码块内访问。{letmessge='你好';console.log(messge);}console.log(messge);//ReferenceError:messgeisnotdefined静态作用域是在词法分析时(编译时)确定的。letnumber=42;functionprintNumber(){console.log(number);}functionlog(){letnumber=54;printNumber();}日志();//42作用域链JavaScript运行时,引擎会先在当前作用域中查找变量。如果找不到,它会逐层搜索父作用域,直到找到最顶层的全局作用域。如果仍然找不到,它将返回undefined。varg='Globalhello'functionf1(){varg1='G1hello';functionf2(){varg2='G2hello'functionf3(){console.log(g,g1,g2)}f3()}f2();}f1();//GlobalhelloG1helloG2helloRunningAnalysisExecutionContext执行上下文是执行一段JavaScript的环境,它存储了一些执行代码所必需的信息。执行上下文分为全局执行上下文和函数执行上下文。程序中只有一个全局执行上下文,除函数外的代码都在全局执行上下文中运行。函数执行上下文,函数每次被调用都会创建对应的函数执行上下文。执行上下文包含变量环境、作用域链和this点。变量环境,函数内部的所有变量和对象引用以及调用参数。作用域链由对当前函数外部变量的引用组成。这指向。从JavaScript运行时的内存结构来看,调用栈是存储的执行上下文的集合。CaseCase1这是一个普通的JavaScript例子,运行过程分析:varmsg='Globalhello'functionsay(){varmsg='Hello'returnmsg;}vars=say();console.log(message)//hello创建全局执行上下文,然后进入调用栈。调用函数say(),创建say()的函数执行上下文,并合并到调用栈中。执行say()函数后返回结果,更新全局执行上下文中的s变量。从堆栈中弹出say函数的执行上下文。Case2这个例子和上面例子的区别在于返回值是一个函数。这个匿名函数也称为闭包。它访问函数外部的变量。即使在外部函数的执行上下文从堆栈中弹出之后,它仍然可以保存对外部变量的引用。运行分析如下:varmsg='Globalhello'functionsay(){varmsg='Hello'returnfunction(){console.log(msg)};}vars=say();s()创建一个全局执行上下文,然后进入调用栈。调用函数say(),创建say()的函数执行上下文,并合并到调用栈中。say()函数执行后返回结果,更新全局执行上下文中的s变量。s是一个函数类型,它仍然持有sayvar=msg的引用。从堆栈中弹出say函数的执行上下文。执行s()并为s()创建函数执行上下文。从堆栈中弹出s()函数的执行上下文。思考题在脑海中动态执行以下代码。题目一:varmsg='Globalhello'functiongetMsgFunc(){varmsg='Hello';函数getMsg(){返回消息;}returngetMsg();}console.log(getMsgFunc());题目二:varmsg='Globalhello'functiongetMsgFunc(){varmsg='Hello';函数getMsg(){返回消息;}returngetMsg;}console.log(getMsgFunc()());题目三:varmsg='Globalhello' varobj={ msg:'Hello', getMsgFunc:function(){ returnfunction(){ returnthis.msg; }; } }; console.log(obj.getMsgFunc()());题目四:varmsg='Globalhello' varobj={ msg:'Hello', getMsgFunc:function(){varthat=this returnfunction(){ returnthat.味精; }; } }; console.log(obj.getMsgFunc()());
