有这么两段小程序。javascript
var goo = "hello"; function foo(){ if(true){ goo = "world"; }else { goo = "world"; } } foo(); console.log(goo);
var goo = "hello"; function foo(){ if(true){ goo = "world"; }else { var goo = "world"; } } foo(); console.log(goo);
毫无疑问,把这两段小程序贴到浏览器里跑一下,能很快地获得答案。
因此关上浏览器,你以为他们的答案分别是什么,为何?java
在第一段小程序中,没有用var去声明变量goo,这在javascript中叫隐式声明,隐式声明是会声明一个全局变量的,因此 goo = "world"; 将会覆盖以前声明的全局变量的值。
因此第一题的答案是world。小程序
而在第二段小程序中,因为在javascript中,var 表达式的值在运行以前将会被转化,JavaScript将会把 var 表达式和 function 声明提高到当前做用域的顶部。也就是说,第二段小程序其实等同于:浏览器
var goo = "hello"; function foo(){ var goo;//var表达式提高到当前做用域的顶部 if(true){ goo = "world"; }else { goo = "world"; } } foo(); console.log(goo);
在第二段小程序中,因为条件语句的控制,也许程序永远不会执行到 var goo = "world" 这一句,可是因为使用了var表达式,就会致使goo变量提高到当前做用域的顶部,进而使goo声明为一个局部变量,这样一来,局部变量赋值并不会影响全局变量,因此第二段程序显示“hello”。code
两段小程序,考考做用域和变量声明提高(Hoisting),怎么样,答对了么?ip