## let和const命令
> 1.let 命令
> 2.块级作用域
> 3.const命令
### let命令
1.用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效
~~~
{
let a = 10;
var b = 1;
}
a // ReferenceError: a is not defined.
b // 1
~~~
2.不存在变量提升
~~~
// var 的情况
console.log(foo); // 输出undefined
var foo = 2;
// let 的情况
console.log(bar); // 报错ReferenceError
let bar = 2;
~~~
3.暂时性死区
~~~
var tmp = 123;
if (true) {
tmp = 'abc'; // ReferenceError
let tmp;
}
~~~
4.不允许重复声明
~~~
// 报错
function func() {
let a = 10;
var a = 1;
}
// 报错
function func() {
let a = 10;
let a = 1;
}
~~~
### 块级作用域
> let实际上为 JavaScript 新增了块级作用域。
一:ES5只有全局作用域和函数作用域,没有块级作用域,会带来以下问题:
1. 变量提升导致内层变量可能会覆盖外层变量
~~~
var a = 5;
function func() {
console.log(a);
if (true) {
var a = 1;
}
}
func(); // undefined
~~~
2) 用来计数的循环变量泄露为全局变量
~~~
for (var i = 0; i < 10; i++) {
console.log(i);
}
console.log(i); // 10
~~~
二:ES6块级作用域
* ES6允许块级作用域的任意嵌套。外层作用域无法读取内层作用域的变量。
~~~
{{{{
{let i = 6;}
console.log(i); // 报错
}}}}
~~~
* 内层作用域可以定义外层作用域的同名变量。
~~~
{{{{
let i = 5;
{let i = 6;}
}}}}
~~~
三: 块级作用域的出现使得立即执行函数不再需要。
> 立即执行函数:
~~~
(function() {
var i = 5;
})();
~~~
> 块级作用域
~~~
{
let i = 5;
}
~~~
四:块级作用域与函数声明
ES5规定,函数只能在顶层作用域和函数作用域之外声明,不能在块级作用域中声明。
~~~
if (true) {
function func() {}
}
try {
function func() {}
} catch {
}
~~~
上面两种函数声明在ES5中都是非法的,但是浏览器没有遵守这一规定,还是支持在块级作用域中声明函数,因此以上两种情况实际都能运行,不会报错;但是,在严格模式下,还是会报错。
~~~
'use strict':
if (true) {
function func() {} // 报错
}
~~~
ES6引入了块级作用域,明确允许在块级作用域中声明函数。
~~~
if (true) {
function func() {} // 不报错
}
~~~
ES6还规定,在块级作用域中,函数声明的行为类似于let,在块级作用域之外不可引用。
ES6中,函数声明会提升到函数作用域的头部。
~~~
function func() {
console.log('out');
}
(function() {
if (false) {
function func() {
console.log(‘in’);
}
}
func();
})();
~~~
在ES5中输出:in
在ES6中输出:out
> 但是在浏览器中执行的时候呢会像如下一样,导致报错!
~~~
function func() {
console.log(‘out’);
}
(function() {
var func = undefined;
if (false) {
function func() {
console.log(‘in’);
}
}
func();
})();
~~~
>>如果改变了块级作用域内声明的函数的处理规则,显然会对老代码产生很大影响。为了减轻因此产生的不兼容问题,ES6 在附录 B里面规定,浏览器的实现可以不遵守上面的规定,有自己的行为方式。
1.允许在块级作用域内声明函数。
2.函数声明类似于var,即会提升到全局作用域或函数作用域的头部。
同时,函数声明还会提升到所在的块级作用域的头部
考虑到环境导致的行为差异太大,应该避免在块级作用域内声明函数。如果确实需要,也应该写成函数表达式,而不是函数声明语句
~~~
// 函数声明语句
{
let a = 'secret';
function f() {
return a;
}
}
// 函数表达式
{
let a = 'secret';
let f = function () {
return a;
};
}
~~~
另外,还有一个需要注意的地方。ES6 的块级作用域允许声明函数的规则,只在使用大括号的情况下成立,如果没有使用大括号,就会报错。
~~~
// 不报错
'use strict';
if (true) {
function f() {}
}
// 报错
'use strict';
if (true)
function f() {}
~~~
### const 语法
1. const声明一个只读的常量。一旦声明,常量的值就不能改变。
2. const一旦声明变量,就必须立即初始化,不能留到以后赋值。
3. const的作用域与let命令相同:只在声明所在的块级作用域内有效。
4. const命令声明的常量也是不提升, 只能在声明的位置后面使用
5. const声明的常量,也与let一样不可重复声明。
~~~
if (true) {
console.log(MAX); // ReferenceError
const MAX = 5;
}
~~~
~~~
var message = "Hello!";
let age = 25;
// 以下两行都会报错
const message = "Goodbye!";
const age = 30;
~~~
6.需要注意的是const只是不允许需改内存地址,对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。
对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指向实际数据的指针,const只能保证这个指针是固定的(即总是指向另一个固定的地址),至于它指向的数据结构是不是可变的,就完全不能控制了
~~~
const foo = {};
// 为 foo 添加一个属性,可以成功
foo.prop = 123;
foo.prop // 123
// 将 foo 指向另一个对象,就会报错
foo = {}; // TypeError: "foo" is read-only
~~~
~~~
const a = [];
a.push('Hello'); // 可执行
a.length = 0; // 可执行
a = ['Dave']; // 报错
~~~
### 课后习题
1.请说出下面的程序执行后返回的值?
~~~
{
let i =7;
}
conosle.log(i);//打印出什么?
{
var i = 7;
}
console.log(i);//打印出什么
~~~
2.下面的代码有哪些问题?
~~~
const x;
x = 2;
~~~
~~~
const b = 2;
b = 3;
~~~
~~~
let i = 3
{
let i = 4;
let i = 5;
{
let i = 6;
}
}
~~~
~~~
{
j = 1;
let j = 3;
}
~~~
- Less
- 课程规划
- Less概述
- 变量
- 混合
- 嵌套
- 继承
- 导入
- 函数
- 其他
- 实战
- ES6
- 课程规划
- ES6概述
- let和const命令
- 变量的解构赋值
- 字符串扩展
- 函数扩展
- 数组扩展
- Set和Map数据结构
- Symbol
- Generator 函数
- Promise对象
- Class语法
- Module 的语法
- ES7和ES8
- 实战
- VUE
- 课程规划
- vue概述
- vue实例
- 模版语法
- 计算属性和侦听器
- Class和Style的绑定
- 条件渲染
- 列表渲染
- 事件处理
- 表单输入绑定
- 组件基础
- 过渡和动画
- 自定义指令
- 过滤器
- 响应式原理
- 实战课程
- Node
- 课程规划
- 课程概述
- node入门实例
- 模块系统
- 回调函数
- 全局对象
- 常用模块介绍
- 常用模块介绍-1
- 常用模块介绍-2
- 常用模块介绍-3
- npm使用
- express的使用
- express的使用-1
- webpack基础
- 实战
- 微信小程序
- 课程规划
- 课程概述
- 基本配置和生命周期
- wxml模版
- wxss
- wxs
- 组件
- 微信API
- 自定义组件开发
- 实战小程序
- Element
- 课程规划
- 课程概述
- 特性介绍
- 组件介绍-基础组件
- 组件介绍-表单组件
- 组件介绍-数据展示组件
- 组件介绍-提示组件
- 组件介绍-导航组件
- 组件介绍-其他组件
- 综合案例