你真的懂let和const吗?
- 块级作用域
在ES6之前我们脑海里应该只存在全局作用域和函数级作用域,没有块级作用域。那么为什么要引入块级作用域呢?
- 避免外层变量被覆盖
var str = "hello";
function d() {
console.log(str);
if (false) {
var str = 'world';
}
}
d();//undefined
相信很多刚入门的同学看到上述代码会有所不解,其实在全局作用域str变量已经被声明且复制,为什么我函数里面访问不到呢。这里就牵扯到变量提升和函数级作用域的概念。上述代码其实等同于下放代码,当函数被执行的时候生成了一个新的作用域也就是函数作用域,js引擎会把变量声明提到方法体的最前面,大家可以看到只是声明了并没有赋值。所以就是 undefined。
var str = "hello";
function d() {
var str ;
console.log(str);
if (false) {
str = 'world';
}
}
d();//undefined
- 循环变量污染全局变量
var str = 'hello';
for (var i = 0; i < str.length; i++) {
console.log(str[i]);
}
console.log(i); // 5
很多同学面试的时候可能会遇到上面类似的代码,疑惑点应该在为什么会打印出来为什么会是5,同样的道理代码如同下方。变量会被提升,所以在循环结束之后i就被累加到了5.
var str = 'hello';
var i;
for ( i = 0; i < str.length; i++) {
console.log(str[i]);
}
console.log(i); // 5
es6的let和const声明符,是不存在变量提升的;同时也只在块级作用域生效。
这个答案应该很明显了吧
var str = "hello";
function d() {
console.log(str);
if (false) {
let str = 'world';
}
}
d();
- 暂时性死区MDN
什么是暂时性死区呢?很多人可能很迷惑。那就听我娓娓道来,如果说我们使用了let和const命令,作用域内会对这些命令声明的变量,在它的声明周期内形成一种封闭作用域。这在语法上,称为“暂时性死区”。代码展示如下:
if (true) {
tmp = 'abc'; // ReferenceError
console.log(tmp); // ReferenceError
let tmp;
console.log(tmp); // undefined
tmp = 123;
console.log(tmp); // 123
}
因为let和const声明是不会被提升的,所以为了保障声明的有效性,js的解释引擎会对变量所处的块级作用域形成一种保护,因此在声明之前使用会有语法错误,是不被允许的。
不能重复声明
function de(){
var a = "1";
var a = "2";
console.log(a);
}
de()//不报错
function de(){
var a = "1";
let a = "2";
console.log(a);
}
de()//报错
function de(){
let a = "1";
let a = "2";
console.log(a);
}
de()//报错
相信大家一般不会声明重复变量编码,所以在这里就不做解释了。如果大家感兴趣可以自己研究或者来现场一起学习。
- const常量
const声明符的大多特性和let相同,这里就不多做解释了。大家都知道const是声明常量的,一但变量被声明成常量它就不能再被继续修改了。大家要注意的是这里变量不可被修改的是存储的地址值不可被修改,意思就是简单类型的数据是不能修改的。复合类型的数据(主要是对象和数组)const只能保证这个指针是固定的,而这个具体的对象实例包含的属性是可以被修改的。看看代码我们可能会更清楚:
//实例一
const a = "hello";
console.log(a);//"hello"
a = "world";//Assignment to constant variable
//实例二
const obj = {};
obj.name = "jack";
console.log(obj.name);//"jack"
obj = {};//Assignment to constant variable.
//实例三
const a = [];
a.push('Hello');
console.log(a); //[ 'Hello' ]
a.length = 0;
a = ['Dave']; // Assignment to constant variable.
正如大家所看到的字符串a被复制后就不能在修改,而对象和数组是可以改变它里面的元素的,但是不能给重新复制一个新的对象实例。由此就可以断定const声明出来的变量存的是固定的地址值。
- 关于es6还有更多的知识点,请关注我接下来的文章。如发现不当之处欢迎加微信(xiaoqiang0672)批评。
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 十大经典排序算法 (动态演示 + 代码)
- 学生成绩管理系统案例
- C 语言指针详解
- 04 CentOS6.5系统语言切换为中文
- 【SpringBoot DB 系列】Redis 高级特性之 Bitmap 使用姿势及应用场景介绍
- 踩坑:一次年轻代GC长暂停问题的解决与思考
- 监听MySQL的binlog日志工具分析:Canal
- 小解c# foreach原理
- 3分钟短文:任命管理员,给Laravel普通用户提权
- this到底是什么?
- ES5面向对象基础
- 面试官问我啥是OAuth 2.0,两个案例讲懂他~
- 年轻代频繁ParNew GC,导致http服务rt飙高
- JWT 使用 nimbus-jose-jwt 进行解码
- linux centos7 编译安装python3 --shell脚本