var 声明会被拿到函数或全局作用域的顶部,位于作用域中所有代码之前。这个现象叫作“提升” 3 (hoisting)。提升让同一作用域中的代码不必考虑变量是否已经声明就可以直接使用。
在实践中,提升也会导致合法却奇怪的现象,即在变量声明之前使用变量。下面的例子展示了在全局作用域中两段等 价的代码
// 等价于: 5
var name = "Jake";
name = 'Jake';
var name;
下面是两个等价的函数:
function fn1() {
var name = 'Jake';
}
// 等价于: function fn2() {
var name;
name = 'Jake'; }
通过在声明之前打印变量,可以验证变量会被提升。声明的提升意味着会输出 undefined 而不是 Reference Error:
console.log(name); // undefined
var name = 'Jake';
function() { 10 console.log(name); // undefined
var name = 'Jake';
}
1. 使用 let 的块级作用域声明
ES6 新增的 let 关键字跟 var 很相似,但它的作用域是块级的,这也是 JavaScript 中的新概念。块 级作用域由最近的一对包含花括号{}界定。换句话说,if 块、while 块、function 块,甚至连单独 的块也是 let 声明变量的作用域。
if (true) {
let a;
console.log(a); // ReferenceError: a 没有定义
while (true) {
let b;
}
console.log(b); // ReferenceError: b 没有定义
function foo() {
let c;
}
console.log(c); // ReferenceError: c 没有定义
// 这没什么可奇怪的
// var 声明也会导致报错
// 这不是对象字面量,而是一个独立的块
// JavaScript 解释器会根据其中内容识别出它来 {
let d; }
console.log(d); // ReferenceError: d 没有定义
let 与 var 的另一个不同之处是在同一作用域内不能声明两次。重复的 var 声明会被忽略,而重 复的 let 声明会抛出 SyntaxError。
var a; var a;
// 不会报错
{
let b;
let b; }
// SyntaxError: 标识符 b 已经声明过了
let 的行为非常适合在循环中声明迭代变量。使用 var 声明的迭代变量会泄漏到循环外部,这种情 况应该避免。
for (var i = 0; i < 10; ++i) {}
console.log(i); // 10
for (let j = 0; j < 10; ++j) {} console.log(j); // ReferenceError: j 没有定义
严格来讲,let 在 JavaScript 运行时中也会被提升,但由于“暂时性死区”(temporal dead zone)的 缘故,实际上不能在声明之前使用 let 变量。因此,从写 JavaScript 代码的角度说,let 的提升跟 var 是不一样的。
标签:console,变量,作用域,js,let,var,声明,name From: https://blog.51cto.com/u_16298172/9166604