ES6学习笔记--let和const
今天开始读阮一峰的《ECMAScript 6 入门》,在这里记录下阅读过程中的要点,以便随时查阅。
let和const
顶层对象的属性与全局变量挂钩,被认为是js最大的败笔之一,ES6开始,全局变量将逐步与顶层对象脱钩。为了保持兼容性,一方面,var和function声明的全局变量,依旧是顶层对象的属性;另一方面,let,const,class命令声明的全局变量,不属于顶层对象的属性:
var a = 1;
window.a;//1
let b = 2;
window.b;//undefined
const 声明一个只读常量,一旦声明就必须立即初始化,否则报错;声明之后不能修改,否则也会报错;
const实际上保证的不是变量的值不可改动,而是变量指向的那个内存地址不得改动。使用const声明引用类型,只能保证指针是固定的,但是指向的数据结构内的属性和方法是可变:
const obj={};
obj.name = 'illidan';
obj.naem; // 'illidan';
obj = {}; //报错,改变了指针的指向
let和const声明的变量只在代码块内有效(代码块:大括号包起来的部分),在代码块外调用会报错
let和const没有变量提升,因此在它们声明之前调用变量会报错
console.log(foo);//undefined
var foo = 'haha'
console.log(a); //reference error
let a = 'hehe';
let和const不允许在相同作用域内,重复声明一个变量:
function foo1(){ //报错var a = 1;let a = 1;
}
function foo2(){ //报错let a = 1;let a = 2;
}
function foo3(){//报错let a= 1;const a = 2;
}
因此不能在函数内部重新声明参数:
function foo4(arg){let arg;//报错
}
function foo5(arg){{let arg;//不报错}
}
for循环有个特别之处,循环语句是一个父作用域,循环体内是一个单独的子作用域
for (let i = 0; i < 3; i++) {let i = 'abc';console.log(i);
}
//3*abc
只要块级作用域内存在let或const,则它们声明的变量就绑定了这个区域,不再受外部的影响,这个区域称为暂时性死区(temporal dead zone),简称TDZ
var temp = 123;
if(true){temp = 'abc';//reference errorlet temp;
}
var const = 1;
if(true){const=2;//reference errorconst const=3;
}
TDZ也意味着typeof不再是一个百分百安全的操作
typeof undeclared_variable //undefined
typeof x;//reference error
let x;
有些TDZ比较隐蔽:
function bar(x=y,y=2){return [x,y]
}
bar();//报错,参数x默认等于参数y,而此时y还没有声明
修改之后
function bar(x=2,y=x){return[x,y];
};
bar();//[2,2]
使用let或者const声明变量时,只有变量还在没有声明完成前使用,就会报错:
var x = x;//undefined
let x = x; // reference error
const y = y; // reference error
总之,TDZ的本质就是,只要一进入当前作用域,所要使用的变量就已经存在了,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量
为什么需要块级作用域?
ES5中只有全局作用域和函数作用域,没有块级作用域,会带来一些不合常理的场景:
第一种场景,内层变量可能会覆盖外层变量
var temp = new Date();
function f(){console.log(temp);if(false){var temp = 'hello world'; //变量提升}
}
f();//undefined
第二种场景,用来计数的循环变量泄露为全局变量:
for(var i=0;i<10;i++){console.log(i);
};
console.log(i); //10
ES6引入块级作用域,明确允许在块级作用域中声明函数,行为类似于let,在块级作用域之外不可引用
function f() { console.log('I am outside!'); }(function () {if (false) {// 重复声明一次函数ffunction f() { console.log('I am inside!'); }}f();
}());
上面的代码在ES5中运行,会得到'i an inside!'
// ES5 环境
function f() { console.log('I am outside!'); }(function () {function f() { console.log('I am inside!'); } //函数声明提升if (false) {}f();
}());
ES6理论上会得到'I am outside!',但是这样处理会对老代码产生很大的影响,为了兼容老代码,浏览器有自己的行为方式:
-允许在块级作用域内声明函数
-函数声明类似于var,即函数名提升到全局作用域或块级作用域头部,函数体不提升
-同时,函数声明还会提升到所在块级作用域的头部
因此,上面的代码在ES6浏览中实际执行的是:
// 浏览器的 ES6 环境
function f() { console.log('I am outside!'); }
(function () {var f = undefined; // 只提升变量名if (false) {function f() { console.log('I am inside!'); }}f();
}());
//f is not a function;
要避免在块级作用域里声明函数,如果确实需要,则要写成函数表达式,而不是函数声明
转载于:https://www.cnblogs.com/azerothmemoir/p/6512453.html
ES6学习笔记--let和const相关推荐
- ES6学习笔记二arrow functions 箭头函数、template string、destructuring
接着上一篇的说. arrow functions 箭头函数 => 更便捷的函数声明 document.getElementById("click_1").onclick = ...
- ES6学习笔记02:let 与 const
ES6学习笔记02:let 与 const 用var声明的变量会造成全局污染,于是就产生了新的声明方式. 1.let 用let声明变量,必须先声明后使用. 在for循环头里用let定义循环变量i,那么 ...
- es6学习笔记-字符串的扩展_v1.0_byKL
es6学习笔记-字符串的扩展_v1.0 字符的Unicode表示法 JavaScript 允许使用uxxxx的形式表示一个字符,但在 ES6 之前,单个码点仅支持u0000到uFFFF,超出该范围的必 ...
- ES6学习笔记(五):轻松了解ES6的内置扩展对象
前面分享了四篇有关ES6相关的技术,如想了解更多,可以查看以下连接 <ES6学习笔记(一):轻松搞懂面向对象编程.类和对象> <ES6学习笔记(二):教你玩转类的继承和类的对象> ...
- es6学习笔记-顶层对象_v1.0_byKL
es6学习笔记-顶层对象_v1.0 (虽然是笔记,但是基本是抄了一次ruan大师的文章了) 顶层对象 顶层对象,在浏览器环境指的是window对象,在Node指的是global对象. ES5之中,顶层 ...
- # es6 学习笔记
es6 学习笔记 let变量 let和var用法级别一样 let不能重复声明,但是var可以 var varIns = "A"; var varIns = "B" ...
- ES6学习笔记(三):教你用js面向对象思维来实现 tab栏增删改查功能
前两篇文章主要介绍了类和对象.类的继承,如果想了解更多理论请查阅<ES6学习笔记(一):轻松搞懂面向对象编程.类和对象>.<ES6学习笔记(二):教你玩转类的继承和类的对象>, ...
- ES6学习笔记04:Set与Map
ES6学习笔记04:Set与Map JS原有两种数据结构:Array与Object,ES6新增两种数据结构:Set与Map 一.Set数据结构 Set类似于数组,但是成员值不允许重复,因此主要用于数据 ...
- ES6学习笔记03:变量的解构赋值
ES6学习笔记03:变量的解构赋值 如果想从复杂数据结构(数组.对象)中获取某一个数据,可能需要大量的遍历操作才能完成.通过解构赋值,这一过程可以得到简化. 1.字符串的解构赋值 其实,Python也 ...
最新文章
- 微信小程序插件功能页开发详细流程
- 中国开发者新福利:大模型API接口出炉,让普通用户玩转内容生成
- Oracle 检索数据
- VS设置DLL所在的调试目录
- MySQL中如何关闭事务的自动提交
- 语义分割 - 数据集准备
- html首页我的待办,JavaScript / HTML中的待办事项列表
- JAVA Map 和 List 排序方法
- 意外发现一个很不错的涂鸦作者
- NGINX下红黑树的删除(终章)附GIF
- 在kettle中实现数据验证和检查
- JasperReport| JasperReport中使用自定义字体(font)
- 使用apache.commons.fileupload 进行文件上传
- 自己动手写网络爬虫学习笔记
- c语言中eof的作用,eof在c语言中表示什么
- Nero 2014 Platinum 白金版 V 15.0.02200 官方版
- IKBC DC-108改装锂电池
- 实战!双硬盘安装图解!
- 关于vs编译器 /GZ 选项的意思
- 吉首大学第九届"新星杯"大学生程序设计大赛(重现赛)(回顾补题)
热门文章
- Springboot整合freemarker和相应的语法
- 轴等比缩放_CAD教程:自由缩放命令的操作流程
- php 搜索名称或者编号,ECSHOP商品关键词模糊分词搜索插件,商品列表关键字加红功能-ecshop插件网...
- signature=3ba70fa0be2ca50c615373e5495718b1,翻译文化观与翻译改写
- java script jquery_Java Script 学习笔记 -- jQuery
- Zookeeper分布式一致性原理(七):Curator客户端
- python聚类分析如何确定分类个数_Python数据挖掘—聚类—KMeans划分法
- Red Hat忘记root密码,重置root管理员密码
- 二叉树重建(c++)
- 微信公众号点击菜单即可打开并登录微站的实现方法