js代码嵌套问题,为什么外层定义的变量内层不能使用

vara=1;(functionf1(){alert(a);vara=2;(functionf2(){alert(a)vara=3;(function(){alert(a... var a = 1;
(function f1 () {
alert(a);
var a = 2;
(function f2(){
alert(a)
var a = 3;
(function() {
alert(a);
})()
})()
})()
这段函数,能否讲解一下,为什么只有a=3能输出来,外层的都是undefined
展开
 我来答
huibo865686
2014-08-29 · TA获得超过916个赞
知道小有建树答主
回答量:325
采纳率:80%
帮助的人:263万
展开全部

是这样的,在js的解释器(编译机制)里的规则是这样的

在作用域中的变量声明和方法声明都会呗编译器在编译的时候,

给强制挪到第一行,在开始执行,并且变量的默认值都是 `undefined`

比如:

(function(){
  //这是一个独立作用域
  var i = 0;
  var a = 1;
  alert(i + a);
})();

经过编译后的代码可能会类似这样

(function(){
  var i , a;//变量的声明会挪到首行,并且变量默认赋值为`undefined`
  i = 0;
  a = 1;
  alert(i + a);
})();

也会有这种情况

(function(){
  alert(a);
  test();
  var a = 1;
  function test(){
    alert('test fn');
  }
})();

编译后的代码:

(function(){
  var a;
  function test(){//方法会直接挪到代码前
    alert('test fn');
  }
  alert(a);
  test();
  a = 1;
})();

所以你会发现,定义的方法,在代码的任何位置都可以调用,就是这个原因,因为编译后的代码,不管你的方法定义在那里,都会帮你挪到首行


另外,你那里的变量,作用域的问题的规则是这样的

如果同名的变量,那么局部作用域的变量优先于外部变量

var a = 1; //这是一个外部定义的变量
(function(){
  alert(a);
  var a = 2;//在这里,又使用`var`声明了一次 `a`,
            //那么这个变量就会覆盖在外面定义的变量`a`
})();

编译后的结果将是这样

var a;
a = 1;
(function(){
  var a;//这里的a就会覆盖外面的变量a,并且编译器会默认赋值undefined
  alert(a);//所以这里就会弹出undefined了
  a = 1;
})();


当人,如果内部没有用`var`声明这个变量,那么外部作用域和内部的作用域就会使用同一个变量

比如这样

var a = 1;
(function(){
  alert(a);//这样这个方法在自己的作用域中无法找到变量`a`,就会去父作用域找变量`a`
           //如果还没找到,就在往父作用域中找,这样直到找到为止
           //或者一直找到global(全局作用域)还没找到变量`a`,
           //就会抛出一个异常(也就是报错) 'ReferenceError : `a` is not defined'
})();
追问
十分感谢!请问相关资料去哪里查找?高级程序设计里面是否有细致的讲解?我现在手头只有一本程序设计,没有权威指南.....
还有,我之前看过一个说法说:“如果之前声明并初始化了变量,重复声明时,如果不重新初始化,那么他的值不变。” 这种说法是完全错的了?
追答
我是看的`javascript 权威指南 第六版` 

关于变量声明和函数作用域,还有声明提前的这块内容是在

3.9章 变量声明
3.10章 变量作用域
3.10.1 函数作用域和申明提前

在一个作用域中,重复声明一个变量是没有关系的,对变量毫无影响,只有给变量赋值的时候才会影响到这个变量的值
因为逗所以扮
2014-08-29 · TA获得超过599个赞
知道小有建树答主
回答量:654
采纳率:0%
帮助的人:102万
展开全部
f1和f2是局部函数,与a = 1不在一个作用域;
f3与a = 3在同一作用域。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式