一旦引擎进入一个作用域是,会先扫描该作用域内的定义语句
ES5
var foo = 1;
(function(){
console.log(foo) ;//undefined
var foo = 2
})();
函数在加载的时候会立即执行,这时候在函数的作用域内,由于有声明foo的语句,故在函数的作用域内foo的值为2,并且是在console.log(foo)之后声明的,根据声明前置,函数中可以等价于
(function(){
var foo ;
console.log(foo) ;//undefined
foo = 2
})();
故console.log(foo)打印出来的是undefined
当然,如果函数中不声明foo的话,那么函数中打印的foo就应该是全局变量中的 foo, 也就是 1
ES6
对于这种不是很符合编程逻辑的行为,ES6 的let 和const 中,引擎将这种行为直接视为错误处理
let foo = 1;
(function(){
console.log(foo) ;//ReferenceError: foo is not defined
let foo = 2
})();
ES6 标准中(一般情况下为严格模式)不允许变量(或者常量)在被定义之前被其他语句所读取,以免出现逻辑性的错误。