【ES6(2015)】新的声明方式 let、const
文章目录
- 1. 作用域
- 2. let
- 3. const
1. 作用域
常见的作用域主要分为几个类型:全局作用域、函数作用域、块状作用域、动态作用域。
对象 | 类型 |
---|---|
global/window | 全局作用域 |
function | 函数作用域(局部作用域) |
{} | 块状作用域 |
this | 动态作用域 |
全局作用域
变量在函数或者代码块 {}
外定义,即为全局作用域
。不过,在函数或者代码块{}
内未定义的变量也是拥有全局作用域的(不推荐)。
var course = "es"// 此处可调用 course 变量
function myFunction() {// 函数内可调用 course 变量
}
如果变量在函数内没有声明(没有使用 var 关键字),该变量依然为全局变量。
// 此处可调用 course 变量function myFunction() {course = "es"// 此处可调用 course 变量
}
以上实例中 course 在函数内,但是拥有全局作用域,它将作为 global 或者 window 的属性存在。
函数作用域
在函数内部定义的变量,就是局部作用域。函数作用域内,对外是封闭的,从外层的作用域无法直接访问函数内部的作用域!
function bar() {var testValue = 'inner'
}console.log(testValue)
// 报错:ReferenceError: testValue is not defined
如果想读取函数内的变量,必须借助 return 或者闭包。
function bar(value) {var testValue = 'inner'return testValue + value
}console.log(bar('fun')) // "innerfun"
闭包的方式:
function bar(value) {var testValue = 'inner'var rusult = testValue + valuefunction innser() {return rusult}return innser()
}console.log(bar('fun')) // "innerfun"
return 是函数对外交流的出口,而 return 可以返回的是函数,根据作用域的规则,函数内部的子函数是可以获取函数作用域内的变量的。
块状作用域
在ES6之前除了全局作用域就是函数作用域,一直没有自己的块状作用域。在 ES6 中已经改变了这个现象,块状作用域得到普及。关于什么是块,只要认识 {} 就可以了。
if (true) {let a = 1console.log(a)
}
在这个代码中, if
后{}
就是“块”,这个里面的变量就是拥有这个块状作用域,按照规则, {}
之外是无法访问这个变量的。
动态作用域
在 JavaScript 中很多同学对this
的指向时而清楚时而模糊,其实结合作用域会对this
有一个清晰的理解。不妨先来看下这段代码:
window.a = 3function test() {console.log(this.a)
}test.bind({a: 2
})() // 2
test() // 3
在这里bind
已经把作用域的范围进行了修改指向了 { a: 2 }
,而 this
指向的是当前作用域对象。
变量的作用域是在定义时决定而不是执行时决定,也就是说词法作用域取决于源码,通过静态分析就能确定,因此词法作用域也叫做静态作用域。 相反,只能在执行阶段才能决定变量的作用域,那就是动态作用域。
2. let
ES6 新增了let命令,用来声明变量。
1.let 声明的全局变量不是全局对象window的属性
var a = 5
console.log(window.a) // 5
let a = 5
console.log(window.a) // undefined
2.用let定义变量不允许重复声明
var a = 5
var a = 6console.log(a) // 6
let a = 5
let a = 6
// VM131:1 Uncaught SyntaxError: Identifier 'a' has already been declared
// at <anonymous>:1:1
3.let声明的变量不存在变量提升
function foo() {console.log(a)var a = 5
}foo() //undefined
上述代码中,a
的调用在声明之前,所以它的值是 undefined
,而不是 Uncaught ReferenceError
。实际上因为 var
会导致变量提升。而对于 let 而言,变量的调用是不能先于声明的:
function foo() {console.log(a)let a = 5
}foo()
// Uncaught ReferenceError: Cannot access 'a' before initialization
4.let声明的变量具有暂时性死区
只要块级作用域内存在let
命令,它所声明的变量就绑定在了这个区域,不再受外部的影响。
var a = 5
if (true) {a = 6let a
}
// Uncaught ReferenceError: Cannot access 'a' before initialization
上面代码中,存在全局变量 a
,但是块级作用域内let
又声明了一个局部变量a
,导致后者绑定这个块级作用域,所以在let
声明变量前,对a
赋值会报错。
ES6 明确规定,如果区块中存在 let
和 const
命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。
总之,在代码块内,使用 let
命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”。
5.let 声明的变量拥有块级作用域
let
实际上为 JavaScript 新增了块级作用域
{let a = 5
}
console.log(a) // undefined
a
变量是在代码块 {}
中使用let
定义的,它的作用域是这个代码块内部,外部无法访问。
3. const
不能被改变的叫做常量,ES5中定义一个常量:
Object.defineProperty(window, 'PI', {value: 3.14,writable: false
})
console.log(PI)
PI = 5
console.log(PI)
const
除了具有let
的块级作用域和不会变量提升外,还有就是它定义的是常量
,在用 const
定义变量后,我们就不能修改
它了,对变量的修改会抛出异常
。
const PI = 3.1415
console.log(PI)
PI = 5
console.log(PI)
// Uncaught TypeError: Assignment to constant variable.
这个代码块中因为对 PI 尝试修改,导致浏览器报错,这就说明 const
定义的变量是不能被修改的,它是只读的。
注意:const 声明的变量必须进行初始化,不然会抛出异常 Uncaught SyntaxError: Missing initializer in const declaration。
需要注意的是,const
实际上保证的并不是变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动。
const obj = {name: 'xiaoming',age: 18
}
obj.school = 'qinghua'
console.log(obj)
// {name: "xiaoming", age: 18, school: "qinghua"}
虽然定义的对象是const
,但是只是保证地址值不变,地址指向的内存空间的值是可以变的。
如何让对象或者数组这种引用数据类型也不被改变呢?
Object.freeze(obj)
// 只是浅层冻结,只会对最近一层的对象进行冻结,并不会对深层对象冻结。
【ES6(2015)】新的声明方式 let、const相关推荐
- ES6学习笔记二 新的声明方式和变量的解构赋值!
新的声明方式 在ES5的时候,我们只有一个声明方式,var!但是在es6中,声明进行了扩展,我们加上ES5的var的申明方式,我们有了三种声明方式: var:它是variable的简写,可以理解成变量 ...
- ES6系列_2之新的声明方式
ES6系列_2之新的声明方式 在ES5中我们在声明时只有一种方法,就是使用var来进行声明,ES6对声明的进行了扩展,现在可以有三种声明方式. (1)var:它是variable的简写,可以理解成变量 ...
- 必须声明标量变量 @sum_level。_ES6系列—新的变量声明方式
在ES5中,变量声明只有var和function以及隐式声明三种,在ES6中则增加了let.const.import和class四种. 1. let 1.1 块级作用域 let声明的变量的作用域是块级 ...
- 三、const常量声明方式
cosnt是es6中常量的声明方式,声明方法和var.let声明方式一样,但是有点不同的是,const声明方式必须立即初始化变量,并且也不能在后面改变他的值 const foo; // SyntaxE ...
- ES6学习笔记02:let 与 const
ES6学习笔记02:let 与 const 用var声明的变量会造成全局污染,于是就产生了新的声明方式. 1.let 用let声明变量,必须先声明后使用. 在for循环头里用let定义循环变量i,那么 ...
- ES6 — ES11 新特性一篇通
一.ES6 1.1.let 变量不能重复声明 有块级作用域 不存在变量提升(必须先声明后使用) 不影响作用域链 <script>//声明变量let a;let b, c, d;let e ...
- ES6~ES12新特性
ES6新特性 let属性 <div class="item">记得刷卡</div> <script type="text/javascrip ...
- TypeScript学习(2)-变量声明 var let const
let.const是js中新的变量声明方式,es5,es6新版本的js语言规范出来的定义,弥补了var的缺陷.const是对let的一个增强,不允许对一个变量再次赋值,一般用于常量. 使用var声明的 ...
- 【面试】HTML5 有哪些新特性?_声明方式
最近看了一些与html基础相关的入门教学视频,心得感悟只有:不同特性的标签记住就好了!但理智告诉我,一切还未正式开始.肿么办?-_-# 是不是可以根据具体html的面试问题对理论知识进行认知拓展与实践 ...
最新文章
- 什么是标签传播算法?为什么要使用标签传播算法?如何使用?
- tomcat 之APR优化
- 使用信号量实现进程间同步
- (转)mysql帮助命令使用说明
- CAT 性能优化的实践和思考
- python同时发大量请求_python http服务器,多个同时请求
- 【NLP】jieba分词-Python中文分词领域的佼佼者
- 通过mysqlnow()函数校正本地(windows)时间与服务器(linux)时间
- Servlet教程第8讲笔记
- iOS 各种证书的作用、有效期、过期的后果和解决办法
- mysql nfs存储_NFS存储服务及部署
- JAVA我的世界给op_我的世界OP指令有哪些 OP权限怎么设置
- js -- others
- 大数据时代比较教育研究范式的转型
- 在线学生信息管理平台
- oracle安装包,psu,ru补丁包下载文档
- 5G与物联网技术趋势分析
- JAVA8 stram 实战
- 【天池】金融风控数据挖掘task1
- 关于wps相同字体大小在不同文档显示不同的问题解决