var let 和const
作为声明变量的关键字是我们接触JavaScript最先接触的知识。因为javascript不同于c或者java这种强类型的语言,定义变量不需要直接明确类型比如int double等。在es6之前声明变量仅需使用var。在es6之后引入了let和const。下面就大致的讲一下三者的区别。
var
首先var关键字声明的变量可以给它赋值任意类型的数值,同时这个变量即使经过初始的赋值,之后也可以将其改变为任意类型的值,虽然不推荐改变一个变量的值的类型,但是在javascript中是可行的。
var message="hello"; //如此便成功定义好了一个名为message的变量
message=10; //
var的声明作用域
在函数中使用var定义的变量将成为这个函数的局部变量,在函数外这个变量将会被销毁。
function test()
{
var message="hello";
}
test();
console.log(message) //出错
如果我们小小的对这段代码做一个改动
function test()
{
message="hello";
}
test();
console.log(message) //hello
当我们在函数作用域里面不使用var声明变量,那么message就会成为一个全局变量。可以在函数的外部访问message。
var的变量提升
var关键字最重要的知识点就在这里,关于变量提升下面用小例子给大家做个演示。
function test()
{
console.log(age)
var age=10
}
test();//undefined
等价于
function test()
{
var age;
console.log(age);
age=10;
}
因为定义变量会将其拉到函数作用域的顶部,所以反复使用var定义一个变量是可以的
function foo()
{
var name="hello"
var name="well"
var name="yet"
console.log(name)
}
foo();//yet
let
let关键字的作用与var关键字差不多但是有一定的区别,首先最重要的一个区别就是let的作用域是块作用域。
if(true){
let message="hello"
console.log(message)//hello
}
console.log(message)//ReferentError message 未定义
let不允许在同一作用域重复声明变量,当然不在同一个块作用域声明是没有问题的。
let age=10;
let age=12;//SyntaxError age已经声明过了。
let name="hello"
console.log(name)//hello
if(true){
let name="hi"
console.log(name)//hi
}
同时let的声明的变量不会在作用域中被提升
console.log(age) //undefine
var age=10
console.log(name)//ReferenceError age未定义
let name="hello"
for 循环的let
在循环中使用var定义变量会发生迭代变量渗透到循环体外部的情况
for(var i=0;i<5;i++)
{
}
console.log(i)//5
使用let就不会发生这种情况
还有使用var时候对迭代变量的奇特声明和修改
for(var i=0;i<5;i++)
{
setTimeout(()=>console.log(i),0)
}
//实际输出5、5、5、5、5
因为迭代变量保存的是导致循环退出的值5 ,执行超时逻辑时,所有的i都是同一个变量,而使用let声明变量时,Javascript引擎会在后台为每一个迭代循环声明一个新的迭代变量,每个setTimeout引用的是不同的实例变量。
const
const和let 行为基本相同,但是const 声明的时候必须同时初始化变量,且不能修改const声明的变量。 当然如果const变量引用的是一个对象,那么修改这个对象的内部属性并不违反const限制
const person={}
person.name='Matt'
同时const不能用于声明迭代变量,但是如果想声明一个不会被修改的for循环变量那是可以实现的,也就是每次迭代都是创建一个新的变量。这对于for-of 和 for -in循环特别有意义。
for(const key in{a:1,b:2}){
console.log(key);
}
//a,b
for(const value of [1,2,3,4,5]){
console.log(value)
}
//1,2,3,4,5
声明风格
尽量减少使用var ,在定义引用类型的时候尽量使用const ,对基本类型在提前知道未来会修改的时候再使用let