系列文章目录
文章目录
目录
前言
ECMAScript 变量是松散类型的,意思是变量可以用于保存任何类型的数据。每个变量只不过是一个用于保存任意值的命名占位符。有 3 个关键字可以声明变量:var、const 和 let 。其中,var 在ECMAScript 的所有版本中都可以使用,而 const 和 let 只能在 ECMAScript 6 及更晚的版本中使用。
一、var声明
语法:var 变量名;
var message = "ECMAScript", name = "Jack", age = 22; var value = 100;
1、var声明作用域
使用var定义的变量会成为包含它的函数的局部变量。function(){ var message = "Hi"; //局部变量,函数执行结束后会被销毁 } test(); //函数执行结束 console.log(message); //Error
此时,可以省略函数体中的var关键字,使message成为全局变量,在调用一次函数后,变量被定义,便可以在函数外部访问到message变量。(但不推荐这么做,因为在局部作用域中定义的全局变量很难维护,并且在严格模式下,这样未声明便赋值会导致抛出ReferenceError)
2、var声明提升
var声明的变量会自动提升到函数作用域顶部。function foo(){ console.log(message); var message = "Hello"; } foo(); //undefined
相当于:
function foo(){ var message; console.log(message); message = "Hello"; } foo(); //undefined
二、let声明
let和var的作用差不多,但是,let声明的范围是块级作用域,而var声明的范围是函数作用域。
if(true){ var age = 16; console.log(age); //16 let gender = "男"; console.log(gender); //"男" } console.log(age); //16 console.log(gender); //ReferenceError:age未定义
不允许同一个块作用域内出现冗余声明。
let age = 16; let age = 18; //SyntaxError:age变量已被声明 { let age = 18; //这里是不同的块作用域,所以不会报错 }
let声明的变量不会在作用域中被提升。在解析代码时,JavaScript 引擎也会注意出现在块后面的let 声明,只不过在此之前不能以任何方式来引用未声明的变量。在let 声明之前的执行瞬间被称为“暂时性死区”,在此阶段引用任何后面才声明的变量都会抛出ReferenceError。
console.log(name); //undefined var name = "Jack"; console.log(age); //ReferenceError:age未声明 let age = 16;
let 在全局作用域中声明的变量不会成为 window 对象的属性。
for 循环中的 let 声明
for(var i = 0; i < 5; i++){ setTimeout(()=>{ //setTimeout(function(),time)延时执行方法 console.log(i); },1000); }
是不是认为会输出0,1,2,3,4
其实会输出5,5,5,5,5
为什么呢?因为这里 i 是使用var声明的,它的作用域是全局的,也就相当于在循环体外部声明了一个变量 i,在执行for循环时,循环体內部有一个延时方法,该方法内部又调用了 i 这个迭代变量,在循环执行结束退出循环时,迭代变量保存的是导致循环退出的值:5,所以,在之后执行延时方法时所有的 i 都是同一个变量,因而输出的都是同一个值。
而在使用 let 声明迭代变量时,JavaScript 引擎在后台会为每个迭代循环声明一个新的迭代变量。每个 setTimeout 引用
的都是不同的变量实例,所以 console.log 输出的是我们期望的值,也就是循环执行过程中每个迭代变量的值。
for(let i = 0; i < 5; i++){ setTimeout(()=>{ console.log(i); },1000); } //会输出0、1、2、3、4
三、const声明
const 的行为与 let 基本相同,唯一一个重要的区别是用它声明变量时必须同时初始化变量,且尝试修改 const 声明的变量会导致运行时错误。
const a = 1; a = 2; //TypeError: Assignment to constant variable. const b; //SyntaxError: Missing initializer in const declaration var c = 5; const c = 6; //SyntaxError: Identifier 'c' has already been declared
其他情况,const 与 let 一致。
总结
最佳声明风格:
1、不使用var
2、const优先,let次之