ES6 学习笔记(一)let、const与作用域
一、let命令
1.1用法
1.1.1 let类似于var,但所声明的变量只在let命令所在的代码块有效。
如:
{
let a = 10
var b = 20
}
console.log(b)
console.log(a)
输出结果:
20
D:\code\Workspace\JS_projects\test\02\01.js:10
console.log(a)
^
ReferenceError: a is not defined
1.1.2 for循环中的变量计数器很适合使用let命令
for (var i = 0; i < 3; i++) {
console.log(1, i)
}
console.log(2, i)
输出结果:
1 0
1 1
1 2
2 3
for (let j = 0; j < 3; j++) {
console.log(1, j)
}
console.log(2, j)
输出结果:
1 0
1 1
1 2
D:\code\Workspace\JS_projects\test\02\01.js:21
console.log(2, j)
^
ReferenceError: j is not defined
1.1.3 for循环在设置循环变量的部分是一个父作用域,循环体内部又是一个独立的子作用域。
如:
for (let i = 0; i < 3; i++) {
let i = 'abc'
console.log(i)
}
运行结果:
abc
abc
abc
1.2 变量提升
var声明的变量无论其实际声明位置在何处,都会被是为声明于所在函数(或全局)的顶部,这就是变量提升
如:
function fn() {
console.log(a);
}
var a = 100;
fn() // 100
1.3 暂时性死区
看如下代码:
var temp = 123456;
if (true) {
temp = 'abc';
let temp;
}
输出结果是:
temp = 'abc';
^
ReferenceError: temp is not defined
ES6明确规定,如果区块中存在let或const命令,则这个区块对这些命令声明的变量从一开始就形成封闭作用域。在代码块内,使用let命令声明变量之前,该变量都是不可用的,这个区域被称为“暂时性死区”。
1.4 不允许重复声明
如:
let a=10;
let a=1;
console.log(a)
// Identifier 'a' has already been declared
var a=10;
let a=1;
console.log(a)
// Identifier 'a' has already been declared
let a=10;
var a=1;
console.log(a)
// Identifier 'a' has already been declared
二、作用域
变量或函数在起作用的区域。
JavaScript采用的是“词法作用域”,即在变量作用域取决于变量所在的代码区域。
ES6中新增了“块作用域”,也包含了ES5中的“全局作用域”和“函数作用域”。
作用域分为全局作用域、函数作用域和块作用域。
2.1 作用域分类
在所有函数之外定义的变量拥有全局作用域,该变量为全局变量。
全局作用域
全局变量可以在当前页面中任何JavaScript代码中访问。
函数作用域:
在函数中声明的变量(包括函数参数)指定在其所声明的函数内被访问。
块作用域:
由{ }界定的代码区域,let声明的变量具备可访问块作用域
作用域实例:
var a = 105
function f1(){
var a = 100
let b = 200
function f2(){
let c = 100
console.log(a,b,c) // 100 200 100
}
f2()
console.log(a,b) // 100 200
console.log(c) // ReferenceError: c is not defined
}
f1()
2.2 作用域链
每一段JavaScript代码(全局代码或函数)都有一个与之关联的作用域链
当JavaScript查找变量x的时候( 变量解析),会从当前作用域开始跟随作用域链向上查找,直到找到x变量的声明,若到达全局作用域中仍未找到,则抛出一个引用错误(ReferenceError)异常。
2.3 ES5可能出现的问题
由于ES5只有全局作用域和函数作用域两种作用域,可能会出现下面的问题。
2.3.1 内层变量可能会覆盖外层变量
var tmp = new Date();
function f() {
console.log(tmp);
if (false) {
var tmp = 'hello';
}
}
f();
输出结果:
undefined
2.3.2 用来计数的循环变量泄露为全局变量
var s='hello';
for(var i=0;i<s.length;i++){
console.log(s[i]);
}
console.log(i);
输出结果:
h
e
l
l
o
5
2.4 let为JavaScript新增了块级作用域
function fl() {
let n = 5;
if (true) {
let n = 10;
}
console.log(n);
}
fl(); //5
ES6允许块级作用域任意嵌套,一对{}即为一个块级作用域。
内层作用域可以定义与外层作用域同名变量。
块级作用域的出现使得ES5中惯用的IIFE(立即执行匿名函数)不再必要了。
三、const命令
3.1 基本用法
声明一个只读的常量,一旦声明,其值不能改变且必须立即初始化。除此之外,与let用法一致。
实例:
const foo={y:10};
foo.x=100;
console.log(foo.x); // 100
foo={n:1000};
console.log(foo) // Assignment to constant variable.
当常量保存的不是一个值,而是一个地址的时候,该常量所引用的对象是可以更改成员的,只是不能更改该常量保存的地址。
3.2 顶层对象
顶层对象在浏览器环境指的是window,在Node中指的是global对象
var定义的变量会关联到顶层对象中,let和const不会。
四、小结
ES6一方面新增了let和const命令所声明的全局变量不属于顶层对象属性,另一方面也允许var和function命令声明的全局变量依旧是顶层对象的属性。
ES6为ES5提供了良好的兼容性。
由于let和const能提供更好的作用域识别,所以尽量采用let声明变量,const声明常量。
ES6 学习笔记(一)let、const与作用域的更多相关文章
- ES6学习笔记<一> let const class extends super
学习参考地址1 学习参考地址2 ECMAScript 6(以下简称ES6)是JavaScript语言的下一代标准.因为当前版本的ES6是在2015年发布的,所以又称ECMAScript 2015:也 ...
- es6学习笔记--let和const
今天学习了es6中的let和const命令,借此整理一下笔记. let : let 和 var 的声明方式一样,但有 var 比不上的优点.下面用 var 和 let 的例子来加深对 let 的理解. ...
- ES6学习笔记(let,const,变量的解构赋值)
1.let: ; i < 3; i++) { let i = 'abc'; console.log(i); } // abc // abc // abc 不存在变量提升,它所声明的变量一定要在声 ...
- ES6 学习笔记 - let和const
let 和 const 命令 学习资料:ECMAScript 6 入门 let 所声明的变量,只在let命令所在的代码块内有效.用途:循环计数器. 如果使用var,只有一个全局变量i: var a = ...
- es6学习笔记2-—symbol、变量与作用域
1.新的字符串特性 标签模板: String.raw(callSite, ...substitutions) : string 用于获取“原始”字符串内容的模板标签(反斜杠不再是转义字符): > ...
- ES6学习笔记<五> Module的操作——import、export、as
import export 这两个家伙对应的就是es6自己的 module功能. 我们之前写的Javascript一直都没有模块化的体系,无法将一个庞大的js工程拆分成一个个功能相对独立但相互依赖的小 ...
- ES6学习笔记<四> default、rest、Multi-line Strings
default 参数默认值 在实际开发 有时需要给一些参数默认值. 在ES6之前一般都这么处理参数默认值 function add(val_1,val_2){ val_1 = val_1 || 10; ...
- ES6学习笔记<三> 生成器函数与yield
为什么要把这个内容拿出来单独做一篇学习笔记? 生成器函数比较重要,相对不是很容易理解,单独做一篇笔记详细聊一聊生成器函数. 标题为什么是生成器函数与yield? 生成器函数类似其他服务器端语音中的接口 ...
- ES6学习笔记<二>arrow functions 箭头函数、template string、destructuring
接着上一篇的说. arrow functions 箭头函数 => 更便捷的函数声明 document.getElementById("click_1").onclick = ...
- ES6学习笔记之块级作用域
ES6学习笔记:块级作用域 作用域分类 全局作用域 局部作用域 块级作用域 全局作用域示例 var i=2; for (var i = 0; i < 10; i++) { } console.l ...
随机推荐
- spring接口多实现类,该依赖注入哪一个?
一.问题的描述 在实际的系统应用开发中我经常会遇到这样的一类需求,相信大家在工作中也会经常遇到: 同一个系统在多个省份部署. 一个业务在北京是一种实现方式,是基于北京用户的需求. 同样的业务在上海是另 ...
- CF914G Sum the Fibonacci (快速沃尔什变换FWT + 子集卷积)
题面 题解 这是一道FWT和子集卷积的应用题. 我们先设 cnt[x] 表示 Si = x 的 i 的数量,那么 这里的Nab[x]指满足条件的 Sa|Sb=x.Sa&Sb=0 的(a,b)二 ...
- java方法---可变参数
可变参数 在方法的声明中,在指定参数类型后面加一个...(省略号) 一个方法中只能指定一个可变参数,它必须是方法的最后一个参数,任何普通参数必须在它之前声明:
- Jenkins JNLP方式启动 Agent
Jenkins Server配置 如果你是通过Nginx代理了jenkins,那么需要调整下Nginx的配置 map $http_upgrade $connection_upgrade { defau ...
- KingbaseES 数据库静默安装
关键字:KingbaseES.V8R6.Silent.Java 一.环境准备 1.硬件环境支持 金仓数据库管理系统KingbaseES支持X86.X86_64,同时支持龙芯.飞腾等国产CPU硬件体系结 ...
- KingbaseES 数据库Windows环境下注册数据库服务
关键字: KingbaseES.Java.Register.服务注册 一.安装前准备 1.1 软件环境要求 金仓数据库管理系统KingbaseES V8.0支持微软Windows 7.Windows ...
- 群晖-使用docker套件部署Prometheus+Grafana
Docker 部署 Prometheus 说明: 先在群辉管理界面安装好docker套件,修改一下镜像源(更快一点) 所需容器如下 Prometheus Server(普罗米修斯监控主服务器 ) No ...
- csp每日习题
欢迎加入:qq群号:1054587486 做题链接:https://csp.ccf.org.cn/csp/index.action?_access_code=1584494752035 点击模拟考试进 ...
- 对比es6class类和构造函数
构造函数 在原来class 类这个语法糖没有出来之前 我们一般会把方法挂在prototype 上 为了防止过多的开辟内存 1 // 构造函数------------------------------ ...
- .Net7 内容汇总(1)
.Net7 RC1发布 在9月14号,.Net7 RC1正式发布了. 按照微软的说法 This is the first of two release candidates (RC) for .NET ...