ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2022-06-12 21:03:49  阅读:95  来源: 互联网

标签:Const name age JS Let var let 声明 变量


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

 

标签:Const,name,age,JS,Let,var,let,声明,变量
来源: https://www.cnblogs.com/jaetyn/p/16368857.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有