关于js的函数提升和变量提升求教

var foo = 3;
function aa(){
    var foo;
    console.log(foo); // undefined ? 为什么不是3
    foo = foo || 5;
    console.log(foo); //5
}

问题如上图,

w3c文档--重新声明js变量,该变量的值不会消失。

var carname="Volvo";
var carname;

这样carname的值确实不会变,
但是为什么在函数里重新声明foo,foo的值会变成undefined而不是3呢?

阅读 2.8k
6 个回答

函数在查找变量时,先从最近的作用域找,找不到再往上一层找。所以第一个语句console.log(foo)找foo变量时,在函数内找,找到的是var foo;故值为undifined,如果没有var foo;这个语句,就会继续往上一层找,这时就是3了。

在函数内是新的作用域 会优先获取最近的作用域的值
所以 你的 aa 函数内声明了 foo 会优先获取本函数内的 foo

函数里面有局部作用域,在函数里面使用var声明foo,这里的foo作用域只局限于函数aa里面, 不再拥有全局作用域,因此它不等同于全局作用域var声明的foo

ES6之前的作用域只有全局作用域和函数作用域两种,ES6之后新增块级作用域。

函数作用域咯,在aa函数里面var foo ,当执行到这一行的时候,编译器会问作用域,是否已经存在foo这个变量,如果没有就在作用域中声明foo变量,结论当然是没有foo这个变量啦,所以就是undefined咯。w3c文档的那个,因为你的变量都是在同一个作用域中的,所以当执行到var carname;这一行的时候,编译器会问作用域,是否已经存在carname这个变量,结论当然是存在呐。不信你把var foo = 3 放到 aa里面,var foo 前面

使用「var」在同一个作用域中,对同一个变量进行多次变量定义时,编译器会采用最后一次定义所赋的值。但当后续定义不存在初始值时,编译器会忽略本次对该字段的定义。在自作用域中对父作用域的变量进行重定义时,尽管当前变量名与父作用域相同,但编译器也会为当前作用域创建一个同名变量,并对其进行初始化(默认为undefined)。JS在执行时,对变量的查询是就近原则,因为当前作用域存在定义的变量,因此当前函数作用域的变量引用不会再向上查找,所以会抛出你当前{}作用域中所定义的变量值。

ES6之前,作用域有两类:函数作用域和全局作用域。函数内部如果声明了,则会优先使用函数内部的声明变量;另外一点,不管在函数作用域内还是全局作用内,若第一次声明并赋值一个变量,第二次只声明未赋值,该变量的值还是第一次声明赋的值。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题