为何函数B的执行上下文未将其激活对象传入函数A的作用域链?
搞懂JavaScript作用域:为什么你的函数A访问不到函数B里的变量?
嘿,我来帮你拆解这个问题~你遇到的这个报错,核心原因是JavaScript采用的是词法作用域(Lexical Scoping),咱们一步步说清楚:
先看你的代码问题出在哪
你的代码是这样的:
function A(){ console.log(myVar); } function B(){ var myVar = 2; A(); } B(); // 抛出"myVar is not defined"错误
函数A是在全局作用域里定义的,所以它的作用域链里只能找到全局变量,完全碰不到函数B内部的局部变量。而函数B里的myVar是B的私有变量,只在B自己的作用域内有效——哪怕你在B里面调用A,A也没法“钻”进B的作用域去拿这个变量,因为A的作用域在它定义的时候就已经固定了。
什么是词法作用域?
简单说:函数能访问的变量,是它定义时所在环境的变量,不是调用时所在环境的变量。这和一些用动态作用域的语言不一样(比如Bash),在动态作用域里,函数调用时会去当前调用环境找变量,但JavaScript不吃这一套。
怎么解决这个问题?
给你几个实用的方案:
1. 把函数A定义在函数B内部
这样A在定义时就处于B的作用域内,自然能访问到B的myVar:
function B(){ var myVar = 2; function A(){ console.log(myVar); } // A定义在B的作用域里 A(); } B(); // 输出2
2. 把myVar作为参数传给A
如果A需要复用,不想嵌套在B里,就把变量作为参数传递:
function A(targetVar){ console.log(targetVar); } function B(){ var myVar = 2; A(myVar); } B(); // 输出2
3. (不推荐)把myVar变成全局变量
虽然能解决问题,但全局变量容易引发命名冲突,尽量少用:
var myVar; // 全局变量 function A(){ console.log(myVar); } function B(){ myVar = 2; A(); } B(); // 输出2
总结一下
记住JavaScript的核心规则:作用域看定义,不看调用。函数的作用域在它写出来的那一刻就确定了,和它在哪被调用没关系。搞懂这个,很多作用域相关的困惑就迎刃而解啦~
内容的提问来源于stack exchange,提问作者Deli Sandor
相关产品推荐
相关产品推荐

