目录

1.var声明变量的问题

2.使用let声明变量

3.使用const声明变量


1.var声明变量的问题

(1)允许重复的变量声明:导致数据被覆盖

var a = 1;
function print() {console.log(a);
}
print();
var a = 2;
print();

(2)变量提升:怪异数据访问、闭包问题

怪异数据访问:即变量提升导致块级作用域内的变量可以在外部访问到

if (Math.random() < 0.5) {var a = "abc";console.log(a);
} else {console.log(a);
}
console.log(a);

图1-2

 闭包问题

var body = document.getElementsByTagName('body')[0];
for (var i = 1; i <= 10; i++) {var btn = document.createElement('button');btn.innerHTML = '按钮' + i;body.appendChild(btn);btn.onclick = function () {console.log(i);}
}

(3)全局变量挂载到全局对象,全局对象成员污染问题

console.log(window.name);
var name = 'abc';
console.log(window.name);

图1-3

2.使用let声明变量

(1)let声明的变量不会挂载到全局对象

let a = 123;
console.log(window.a);

图2-1

(2)let不允许在当前作用域内重复声明,在块级作用域中用let声明的变量在作用域外不能访问

【例】重复声明变量会报错

let a = 123;
let a = 456;

图2-2-1

【例】作用域外访问块级作用域的变量会报错

{let a = 123;
}
console.log(a);

图2-2-2

(3)使用let不会有变量提升,因此不能再let定义变量之前使用该变量

【例】在变量声明前去访问该变量会报错

console.log(a);
let a = 123;

图2-2-3

【注】该错误提示为:不能在a初始化之前访问,而不是a未被定义,可见在底层实现上,let声明的变量实际上是提升了,拓展如下

(1)底层实现上,let声明的变量实际上也会有提升,但是提升后会将其放到“暂时性死区”,如果访问的变量位于暂时性死区,则报错如图2-2-3,当代码运行到该变量的声明语句时,会将其从暂时性死区中移出

(2)在循环中,用let声明的循环变量会被特殊处理,每次进入循环体都会开启一个新的作用域,并且将循环变量绑定到该作用域,则每次循环使用的是一个全新的循环变量

(3)在循环中,使用let声明的循环变量在循环结束后会销毁

【例】解决闭包问题

let body = document.getElementsByTagName('body')[0];
for (let i = 1; i <= 10; i++) {let btn = document.createElement('button');btn.innerHTML = "按钮" + i;body.appendChild(btn);btn.onclick = function () {console.log(i);}
}

3.使用const声明变量

const和let基本相同,区别在于用const声明的变量,必须在声明时赋值,而且不可以重新赋值

【例】在声明时未赋值,报错

const a;
a = 1;
console.log(a);

图3-1

【注】该报错信息为:在变量声明时没有初始化

【例】修改const声明的变量,报错

const a = 1;
a = 2;
console.log(a);

图3-2

实际上,在开发中应该尽量使用const来声明变量,以保证变量的值不会随意篡改,原因如下:

  • 根据经验,开发中的很多变量,都是不会更改的,也不应该更改
  • 后续的很多框架或者第三方JS库,都要求数据不可变,使用常量可以一定程度上保证这一点

【注】

(1)常量不可变,是指声明的常量的内存空间不可变,并不保证内存空间中的地址指向的其他空间不可变【例】

const a = {name: 'jwh',age: 18
};
a.name = 'zdw'
console.log(a);

【结果】

图3-3

(2)常量的命名

  • 特殊的常量:该常量从字面意义上,一定是不可变的,比如圆周率、月地距离或者其他一些绝不可能变化的配置。通常,这些常量的名称全部使用大写,多个单词之间用下划线分割
  • 普通的常量:命名规则与之前相同

(3)在for循环中,循环变量不可以使用常量【例】

var arr = [{name:'jwh'},{age: 18}]
for (const i = 0; i < arr.length; i++) {console.log(arr[i]);
}

【结果】

图3-4

【例】forin循环可以用const声明变量

var obj = {name: 'jwh',age: 18
}
for(const prop in obj) {console.log(obj[prop]);
}

【结果】

图3-5

ES6的变量声明详述相关推荐

  1. ES6笔记 -- 变量/语句声明

    关于变量声明 let的作用是声明一个作用域为某个代码块({})的变量(称为块级作用域) let不允许变量提升(注: 变量的使用在声明之前) 块级作用域里的let命令之前的区域称之为'暂时性死区', 这 ...

  2. ES5和ES6中的变量声明提升

    ES5和ES6中的变量声明提升 Example1: a=2; var a; console.log( a ); //结果为2 Example2: console.log( a ); //结果是unde ...

  3. 为什么let在php中报错,ES6系列之声明变量let与const

    本篇文章主要是向大家分享了关于ES6系列的声明变量let与const,有兴趣的朋友们可以参考一下本文中的内容 简介 概念 ES6 的第一个版本,在 2015 年 6 月发布了,正式名称就是<EC ...

  4. ES6新特性_let变量声明以及声明特性---JavaScript_ECMAScript_ES6-ES11新特性工作笔记003

    技术交流QQ群[JAVA,C++,Python,.NET,BigData,AI]:170933152 首先看es6的第一个变量声明特性,以前咱们用 var 声明,现在可以用let来声明变量. 可以看到 ...

  5. es6中变量/常量的声明以及区别

    var / let /const var声明变量 var存在全局作用域和函数作用域两种,并且有变量提升 let声明变量 const声明常量 let和const对比var声明有以下特性/区别 变量声明不 ...

  6. php变量 声明提升,TypeScript:let和const变量声明

    在开始介绍let和const变量声明前,有必要先了解下JavaScript里的var变量声明. var变量声明 全局声明 var声明在函数体外,所声明的变量为全局变量.var name = " ...

  7. 必须声明标量变量 @sum_level。_ES6系列—新的变量声明方式

    在ES5中,变量声明只有var和function以及隐式声明三种,在ES6中则增加了let.const.import和class四种. 1. let 1.1 块级作用域 let声明的变量的作用域是块级 ...

  8. TypeScript 变量声明

    TypeScript 变量声明 本节介绍 var let const 这三种变量的声明方式,重点讨论作用域与变量提升的相关知识点,这部分往往也是面试常考部分,需要多加注意. 1. 慕课解释 TypeS ...

  9. [ES6] 细化ES6之 -- 变量的解构赋值

    变量的解构赋值 解构赋值是什么 ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值 var/let [变量名称1,变量名称2,...] = 数组或对象 本质上,这种写法属于"模式 ...

最新文章

  1. ElasticSearch 面试 4 连问,你顶得住么?
  2. R 语言中 X11 相关的一些问题
  3. 2019全球信息通信业热点回顾
  4. kaliLinux下保持匿名
  5. 系统服务器巡查表,服务器操作系统巡检表
  6. Linux命令——mv
  7. 【在线画流程图】网站
  8. 云炬创业政策学习笔记20210111
  9. 使用 js 设置组合快捷键,支持多个组合键定义,还支持 React
  10. [已解决问题] Could not find class XXX referenced from method XXX.YYY
  11. bug2-Internal Error: Blas GEMM launch failed 问题
  12. JavaAPI在线帮助文档
  13. 山大往年自招计算机系试题,山大自招现场:考生笔试说“容易”体测喊“难”...
  14. 用c语言输出英文字母表音标,26个英文字母表中文
  15. 【转】成像的清晰度、分辨率和锐度
  16. Spark Streaming读取Kafka数据的两种方式
  17. 关于微信聊天中的语音开发
  18. YUV图解 (YUV444, YUV422, YUV420, YV12, NV12, NV21)
  19. Mac OSX 苹果电脑 安装 MacPorts
  20. 使用C语言完成舞伴问题(数据结构)

热门文章

  1. 使用 GDB 调试 Android 应用
  2. [转]I,P,B帧和PTS,DTS的关系
  3. Soul网关发布2.1.X之后,它到底有多方便?
  4. 刁钻!你和队友之间选一个淘汰,你怎么选?
  5. 数据结构--图(Graph)详解(二)
  6. Django模型(一)
  7. 【今晚七点半】:5G时代的云游戏还缺什么?
  8. 视频传输面临的挑战和解决之道
  9. 别琢磨了,七夕礼物都给你想好了
  10. 轻松 Flutter 入门,秒变大前端