这段js代码打印出来的结果为什么是这样的?

一流的人
  • 696
var a = 1;
var b = function(){
    console.log(a);  // function a(){}
    a = 10;
    console.log(a);  //10
    return;
    function a(){} //声明提升
}
b();
console.log(a);   //1 为什么是这个数?

最后打印出来的a值,不应该是10吗?为什么是1呢?

评论
阅读 3k
14 个回答

函数声明同时也创建了一个和函数名相同的变量
参考:MDN函数——Function构造函数vs函数声明vs函数表达式
所以,函数作用域中的代码执行顺序就相当于下面这样了:

var b = function(){
    var a;//函数声明提升的同时创建了一个同名的变量
    function a(){}
    console.log(a);//函数声明覆盖变量声明,结果为function a(){}
    a = 10;
    console.log(a);//变量初始化覆盖函数声明,结果为10
    return;    
}

这表明在b函数作用域内又声明了一个变量a,覆盖了全局变量a,发生的一切都是在函数作用域内。
b函数外的console.log(a);访问的自然是全局变量a了,因为它访问不到b函数作用域内的变量。

关于变量声明提升VS函数声明提升,顺序谁在前谁在后参考变量声明提升VS函数声明提升

我的理解,function a(){},相当于在局部作用域b函数中定义了一个a函数,a=10是对b作用域中的a赋值,此时局部作用域b中的a从函数变成一个常量。至始至终没有改变b外作用域中的a=1的值。

因为b函数里面的a=10并不是全局变量啊,而是对function a(){} 的重新赋值 。^_^!

其实,你已知道声明提升,只是最后被代码搞乱了而已,把它整理成下面这样,就一目了然了,全局的变量a就没被改变过:
var a = 1;
var b = function(){
var a = function (){};

console.log(a);
a = 10;
console.log(a);
return;
//function a(){}

}
b();
console.log(a);

声明有有两种,且仅有两种,var 以及 function ,所以调用了 b()就相当于在里面开了块动态内存,重新声明了个变量 a,这两个a 所处的内存位置都不一样,自然不是同一个了,b(){}里面的a,根本就不是外面的a,而且把b()调用执行了一次,那块内存就消失了。故尔,他们说外面的为全局变量,里面的就是局部变量,就是这个道理了!

既然都理解了function a(){}是函数的提前声明,怎么会不理解输出1呢,一开始在函数内部声明了一个局部变量a,由于执行上下文的特性缘故,执行函数时a变量就是一个函数了a=10只是将你内部的局部变量更改了,也就是把你的那个function改变为了'number'类型的变量,执行函数后,这个局部变量就会被销毁。

b里的a,实际是function

var a = 1;
var b = function(){
    console.log(a);
    a = 10;
    console.log(a);
    return;
    function a(){}
}
b();
console.log(a);

你也知道 b 函数里的 function a(){} 提升了,所以 b 函数里所有对 a 的操作其实都是重新赋值

这里说的 a 是局部的,是 b 函数内的
这里说的 a 是局部的,是 b 函数内的
这里说的 a 是局部的,是 b 函数内的

所以最后一句 console.log(a) 是打印全局的 a,也就是一开始初始化的 1

js中函数有局部作用域,因此函数内部的a和外部的a并不是一个变量。

变量的作用域不一样,前一个是全局变量,后一个是局部变量

很明显 最下面那个console是在Window作用域下,那window下的a是多少呢,是1。函数里面的执行顺序是这样的,function a(){},先声明了方法a,然后重新赋值了a=10,这个a是对方法a的赋值。

jasonqiao
  • 1
新手上路,请多包涵

作用域啊!你那函数b中由于由于声明提升a最初是函数,然后又变成数字。但它只有在调用b函数时执行一次,然后就从内存中清楚了。一点也没有影响全局的a,所以a值还是1。

我觉得你可能忽略的一个知识点:函数声明同时也创建了一个和函数名相同的变量。这样一来函数作用域内部的执行顺序如下:

var b = function() {
    var a;
    function a(){};
    console.log(a);//a()
    a=10;
    console.log(a);//10
  }
宣传栏