在js中定义变量的方式有三种,其中let和const关键字是来自ES6中的,下面将逐一介绍各个关键字声明变量的特点。

var声明变量

var 是一个 JS关键字,用来声明变量( variable 变量的意思 )。使用该关键字声明变量后,计算机会自动为变量分配内存空间,不需要程序员。

1.js可以允许变量不声明直接使用

2.js中使用var声明的变量没有块级作用域

Js中没有块级作用域(在ES6之前)。

if(true){var num = 123;console.log(123); //123
}
console.log(123); //123

由于js中没有块级作用域,所以在if内部定义的变量,在外部也可以直接调用进行访问。

let声明变量

ES6中新增用于声明变量的关键字let.

1.let声明的变有块级作用域

在es6之前,声明的变量是没有块级作用域的概念,但是在es6中用let声明的关键字有块级作用域。

• 块作用域指的是由 { } 包括。

• 在其他编程语言中(如 java、c#等),在 if 语句、循环语句中创建的变量,仅仅只能在本 if 语句、本循环语句中使用,如下面的Java代码:

java有块级作用域:

if(true){int num = 123;system.out.print(num);  // 123
}
system.out.print(num);    // 报错

以上java代码会报错,是因为代码中 { } 即一块作用域,其中声明的变量 num,在 “{ }” 之外不能使用;

而与之类似的JavaScript代码由于没有块级作用域的概念,则不会报错(Js中没有块级作用域(在ES6之前))

 if(true){var num = 123;console.log(123); //123
}console.log(123);   //123

但是ES6中固定使用let关键字声明的变量有块级作用域

if (true) { let a = 10;}
console.log(a) // a is not defined

注意:使用let关键字声明的变量才具有块级作用域,使用var声明的变量不具备块级作用域特性。

2.let声明变量不存在变量提升

JavaScript 代码是由浏览器中的 JavaScript 解析器来执行的。JavaScript 解析器在运行 JavaScript 代码的时候分为两步:预解析和代码执行。

  • 预解析:在当前作用域下, JS 代码执行之前,浏览器会默认把带有 var 和 function 声明的变量在内存中进行提前声明或者定义。
  • 代码执行: 从上到下执行JS语句。

注意: 预解析会把变量和函数的声明在代码执行之前执行完成。

变量预解析:

预解析也叫做变量、函数提升。
变量提升(变量预解析): 变量的声明会被提升到当前作用域的最上面,变量的赋值不会提升。

console.log(num);  // 结果是多少?
var num = 10;      // ?结果:undefined

由于javascript有变量提升机制,所以可以在变量的声明之前就调用该变量,因为变量提升会将变量的声明提升到最前面,但是变量的提升不会对值进行提升,所以变量没有赋值之前的默认值是undefined.

但是由于变量的提升导致在日常的开发中,会遇到很多奇怪的问题,所有ES6规定,使用let关键字声明的变量没有变量的提升。

console.log(a); // a is not defined
let a = 20;

注意:使用let关键字声明的变量才没变量的提升,使用var关键字声明的变量依旧有变量的提升。

3.暂时性死区

在js中采取从上一级就近原则的方式来查找变量最终的值。

但是利用let声明的变量会绑定在这个块级作用域,不会受外界的影响。

var temp = 123;if (true) {temp = "abc";let temp;console.log(temp);}

按照以前的就近原则的特点,此时控制台因该输出“abc”,但是结果真的是这样吗?

在ES6中规定,使用let关键字声明的变量在块级作用域中具有暂时性死区的特性。简单来讲,就是在块级作用域中使用let声明的关键字要符合let关键字的性质,和以前的不一样。

例如:上面的例子由于在块级作用域声明了temp变量,但是在声明temp之前,尽然对temp变量赋值“abc”,这就触犯了let关键字没有变量提升的规则,在还没声明变量之前就给未声明的变量赋值,报错。


不能再初始化之前访问“temp”.

注意:只有使用let关键字声明的变量才有暂时性死区的特性。

4.let可以防止循环变量变成全局变量


经典面试题图解:此题的关键点在于每次循环都会产生一个块级作用域,每个块级作用域中的变量都是不同的,函数执行时输出的是自己上一级(循环产生的块级作用域)作用域下的i值.

5.小结

  • let关键字就是用来声明变量的
  • 使用let关键字声明的变量具有块级作用域
  • 在一个大括号中 使用let关键字声明的变量才具有块级作用域 var关键字是不具备这个特点的
  • 防止循环变量变成全局变量
  • 使用let关键字声明的变量没有变量提升
  • 使用let关键字声明的变量具有暂时性死区特性

const声明常量

声明常量,常量就是值(内存地址)不能变化的量。

1.具有块级作用域

 if (true) { const a = 10;}
console.log(a) // a is not defined

2.声明变量的时候必须赋值

const PI; // Missing initializer in const declaration

3.常量赋值后,值不能修改

const PI = 3.14;
PI = 100; // Assignment to constant variable.const ary = [100, 200];
ary[0] = 'a';
ary[1] = 'b';
console.log(ary); // ['a', 'b'];
ary = ['a', 'b']; // Assignment to constant variable.

由于使用const声明的常量赋值之后不能修改,这就有点像java中使用private修饰的变量。例如上面的例子,PI由于声明的时候进行了赋值操作,所以就不能进行二次赋值操作,但是对于数组而言由于const关键字声明的常量是ary,所以对于ary是不能进行二次赋值,但是对于数组储存的值是不属于const管的。const管理的只是const声明的变量不能二次赋值,而对于变量中储存的是什么,是没有约束力的。

4.小结

  • const声明的变量是一个常量
  • 既然是常量不能重新进行赋值,如果是基本数据类型,不能更改值,如果是复杂数据类型,不能更改地址值。
  • 声明 const时候必须要给定值

let、const、var 的区别

  • 使用 var 声明的变量,其作用域为该语句所在的函数内,且存在变量提升现象
  • 使用 let 声明的变量,其作用域为该语句所在的代码块内,不存在变量提升
  • 使用 const 声明的是常量,在后面出现的代码中不能再修改该常量的值

var let const声明变量的区别相关推荐

  1. var,let,cont声明变量的区别

    1.var -支持全局.函数作用域 -接受重复声明 -变量预解析 // 作用域 var aa=1; function fn(){var aa=10;console.log(aa); } fn();// ...

  2. var,let,const 声明中一般人不知道的几个点

    关于var,let,const 声明变量时,有几个特别注意的点,面试的时候极容易被问到,但是很多人特别容易说不清.let的作用域呀,暂时性死区,const作用域等. 文章目录 前言 一.小姐姐知道的l ...

  3. 使用var、let、const声明变量

    一.使用var声明变量 1.使用方法 通过var关键字可以一次声明一个变量或者多个变量,同时可以为声明的变量赋初始值.但是变量的声明和初始值并不是在同一时间执行的,在执行初始值之前这些声明的变量的值为 ...

  4. JS红书宝--var,let和const声明变量

    var,let和const声明变量 var 声明 var声明作用域 function test() { var message = "hi"; // 局部变量 } test(); ...

  5. 详解var、let、const关键词声明变量的区别,以及变量提升、块级作用域的认识等。

    首先回顾一下JavaScript中var声明变量的基础知识: • 在使用var关键词声明变量时,变量在函数外则是全局变量,有全局作用域,全局变量在页面关闭后销毁:变量在函数内则是局部变量,作用局部作用 ...

  6. vue之var和let声明变量

    为什么推荐let而不是以前的var 现在很多编辑器在你使用var声明变量时,var下面会有浅色的波浪线提示,此时建议我们使用let来声明.为什么呢?(闲得无聊,码码字) var 和let 的区别 因为 ...

  7. java val变量声明_Kotlin 中 var 与 val 定义变量的区别,及使用场景

    看 Kotlin 项目示例代码中,经常出现 var / val 定义变量的情况.于是查了一下两者的区别: var 定义的变量可以被再次赋值.var 是 variable 的缩写. val 定义的变量不 ...

  8. python类变量与__init__声明变量的区别

    类变量:可在类的所有实例之间共享的变量 实例类对象:类的实例是调用类对象来创建的.如:par = Parent(),par就是类Parent的一个实例类对象. 实例变量(成员变量):同一个类对象可以创 ...

  9. python类定义变量_python类变量与__init__声明变量的区别

    类变量:可在类的所有实例之间共享的变量 实例类对象:类的实例是调用类对象来创建的.如:par = Parent(),par就是类Parent的一个实例类对象. 实例变量(成员变量):同一个类对象可以创 ...

最新文章

  1. 微信小程序(11)--购物车
  2. Java IO流之转换流
  3. [最新答案V0.4版]微软等数据结构+算法面试100题[第41-60题答案]
  4. 一个老外如何丑化中国程序员
  5. 3、PV、UIP、UV指的是什么
  6. Qt 如何处理密集型耗时的事情
  7. AIX errdemon 命令
  8. linux内核那些事之ZONE
  9. 优秀!Python神器NumPy 论文终登上了 顶刊Nature!
  10. nand flash驱动编写步骤
  11. JavaScript 的 async/await 理解(4)
  12. javascript ()、[]、{}的区别
  13. OFD文件结构--OFD.xml
  14. 网站COM组件调用失败解决办法
  15. MySQL 如何使用show processlist进行过滤
  16. python 答题卡识别项目_答题卡图像识别项目
  17. 拜日式精准引导词_108遍经典拜日式引导词
  18. ps更换证件照底色(视频版)
  19. 宋宝华:论一切都是文件之匿名inode
  20. 正则表达式转NFA,DFA,最小化DFA

热门文章

  1. 如何比较传统WAN与SD-WAN?有什么差别? Vecloud微云
  2. Vue前端-Flask后台跨域访问问题的处理
  3. 用命令行为MySQL设置/修改管理员密码
  4. codewars--js--Hamming Numbers
  5. python3 tensorflow 安装
  6. MySQL的介绍以及使用
  7. na na na na na ~
  8. EditText获得焦点后,如何关闭软键盘
  9. 使用HTML文件作为中转生成WORD文档
  10. C语言内存泄露很严重该怎么办?这几招告诉你