Javascript

JS中Var,Let,Const的使用和区别

本文主要是介绍JS中Var,Let,Const的使用和区别,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

1.Var关键字

(1)Var声明作用域

如果使用var在函数内部定义了一个变量,就意味着该变量将在函数退出时被销毁

具体代码如下:

function test(){
   var message='hi';    //局部变量 
} 
test();
console.log(message) //出错!

不过如果在函数内部声明变量的时候省略var操作符,则可以创建一个全局变量:

function test(){
   message='hi';    //局部变量 
} 
test();
console.log(message) //  hi

(2)Var声明提升

function foo(){
  console.log(age);
  var age=26;    
}
foo();     //undefine

同时反复声明同一个变量也没问题

function foo(){
  var age=26; 
  var age=36; 
  var age=46; 
  var age=56; 
  console.log(age);
}
foo();     //56

2.let声明

let跟var的作用差不多,但是有着重要的区别,最明显的是,let的范围时块作用域,而var声明的范围是函数作用域。

if(true){
   var name='Matt';
   console.log(name);   //Matt
}

console.log(name);    //Matt


if(true){
    let age=26;
    console.log(age);  //26
}
console.log(age);     //ReferenceError;  age 没有定义

注意重复定义的问题

var name;
var name;


let age;
let age;   //SyntaxError 标识符age已经被声明过

JavaScript引擎会记录用于变量声明的标识符及其所在的块作用域,因此嵌套使用相同的标识符不会报错,而这是因为同一个块中没有重复声明:

var name ='Nicholas';
console.log(name);   //  Nicholas

if(true) {
    var name='Matt';
    console.log(name);
}

let age=30;
console.log(age);   //30
if(true){
    let age =26;
    console.log(age);  //26
}

对于声明冗余报错不会因混用let和var而受影响。这两个关键字声明的并不是不同类型的变量,它们只是指出变量在相关作用域如何存在。

var name;
var name;


let age;
let age;   //SyntaxError 标识符age已经被声明过

(1)暂时性锁区

let与var另外一个重要的区别,就是let声明的变量不会在作用域中被提升

// name会被提升
console.log(name);
var name= name='Matt';


//age不会被提升
vonsole.log(age);   //ReferenceError;  age没有被定义
let age=26;

在解析代码时候,JavaScript引擎会注意到出现在块后面的let声明,只不过在此之前不能以任何方式来引用未声明的变量。在let声明之前的执行顺序被称为‘暂时性锁区’,在此阶段引用任何后面才声明的变量都会抛出ReferenceError。

(2)全局声明

与var关键字不同,使用let在全局作用域中声明的变量不会成为window对象的属性(var声明的会)

var name='Matt';
console.log(window.name);    //'Matt'

let age=26;
console.log(window.age);  //undefined

不过。let声明仍然是在全局作用域中发生的,相应变量会在页面的声明周期内存续,因此,为了避免SyntaxError,必须确保页面不会重复声明同一个变量。

(3)条件声明

在使用var声明变量时候,由于声明会被提升,Javascript引擎自动将多余的声明在作用域顶部合并为一个声明,因为let的作用域是块,所以不可能检查前面是否已经使用过let声明过同名变量,同时也就不可能在没有声明的情况下声明它。

<script>
    var name="aa"
    let age=26;
</script>
<script>
    var name="bb"
    let age=213;
      
</script>


<script>
    if(typeof name==='undefined'){
    let name;
    
}
//name被限制在if{}块的作用域内
//因此这个赋值形同于全局赋值
name='Matt';


try{
    console.log(age);
     }
catch{
    let age;
}
  age=26;
//age被限制在catch{}块的作用域内
//因此这个赋值形同于全局赋值
</script>

 

使用try/catch操作符也不能解决,因为条件块中let声明的作用域仅限该块

(4)for循环中的let声明(重要)

在let出现之前。for循环定义的迭代变量会渗透到循环体外部

for (var i=0;i<5;i++)
{
  //循环体  

}
console.log(i)   //5

改成let之后

for (let i=0;i<5;i++)
{
  //循环体  

}

console.log(i)   //ReferenceError:i没有定义

在使用var的时候,最常见的问题是对迭代变量的奇特声明和修改:

for (var i=0;i<5;++i)
{
  setTimeout(()=>console.log(i),0)  
}
//你可能以为的输出0,1,2,3,4
//实际上5,5,5,5,5

1.之所以会这样看,是因为在退出循环时,迭代变量保存的是导致循环退出的值:5.在之后执行超时逻辑时候,所有的i'都是同一个变量,因而输出的都是同一个最终值。

2.而在使用let声明迭代变量时候,Javascript引擎在后台会为每一个迭代循环声明有ige新的迭代变量。每个setTimeout引用的都是不同的变量实例,所以输出的是我们所想要的,也就是循环执行过程中每个迭代变量的值。

3.这种每次迭代声明一个独立变量实例的行为适用于所有风格的for循环,包括for-in和for-of循环。

4.这种每次迭代声明一个独立变量实例的行为适用于所有风格的for循环,包括for-in和for-of循环。

3.const声明

行为与let基本相同,唯一一个重要的区别在于它声明的变量必须同时初始化变量,且尝试修改const声明的变量会导致运行时错误

const age=26;
age=36;   //TypeError:给常量赋值


//const也不允许重复声明
const name='Matt';
const name='Nicholas';  //SyntaxError


//const声明的作用域也是块
const name='Matt';
if(true){
  const name='Nicholas';  
}
console.log(name);   //Matt

const声明的限制只适用于它指向的变量的引用,换句话说,如果const变量引用的是一个对象,那么修改这个对象内部的属性并不违反const的限制(数组也可以)

const person={};
person.name='Matt';    //os

即使Javascript引擎会为for循环的let声明并创建独立的变量实例,而且const变量跟let变量很相似,也不能用const声明去替代迭代变量(因为迭代变量会自增)

for (const i=0;i<10;i++){}  //TypeError;给变量赋值

不过,如果你只想用const声明一个不会被修改的for循环变量,那也是可以的。也就是说,每次迭代只是创建一个新的变量。这对for-of和for-in循环特别有意义;

let i=0;
for (const j=7;i<5;==i)
{
  console.log(j);  
}

//7,7,7,7,7

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

 

这篇关于JS中Var,Let,Const的使用和区别的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!