var ,let,const 的区别:
1、 块级作用域;
2、 不存在变量提升;
3、 暂时性死区;
4、 不可重复声明;
5、let ,const,声明的全局变量不会挂在顶层对象下面;
const 命令两个注意点:
1、 const声明之后必须马上赋值,否则会报错;
2、 const简单类型一旦声明就不能更改,复杂的类型(数组,对象)指针指向的地址不能更改,内部数据可以更改
#### 块级作用域:
es5只有全局作用域和函数作用域,没有块级作域;
-
这样在es5 中会有很多不合理的场景
1、 内层变量的可能覆盖外层变量;
2、 用来技术的循环变量泄露为全局变量
var temp = new Date() function fn (){ console.log(temp);// 相打印外层的作用域 if(false){ var temp = 'hello world';// 这里声明的作用域为这整个函数 } } fn();// 输出的结果为 undefind 未定义 var num = 'hello'; for(var i =0;i<num.length;i++){ console.log(num[i]);// i应该维持for循环使用的变量 } console.log(i);// 全局范围都可以访问到
块级作用域:
例子:
function fn(){
let num = 5;
if(true){
let num = 10;
console.lof(num);// 10 内层的num
}
console.log(num);// 5 外层的num
}
不存在变量提升:
变量提升的现象:
- 在同一作用域下,变量可以在声明之前使用,值为undefind
- es5 使用的是var,声明变量,经常会出现变量提升的现象
// var 声明的变量;
console.log(num);// 输出的结果为undefind
var num ='柚子小哥哥'
// 使用let的声明的变量
console.log(op); 报错ReferenceError
let op = 'hello world'
暂时性死区:
- 只要一进入当前作用域,所要使用的变量就已经存在了,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量
var tmp = 123; // 声明
if (true) {
tmp = 'abc'; // 报错 因为本区域有tmp声明变量
let tmp; // 绑定if这个块级的作用域 不能出现tmp变量
}
不能重复声明:
- let 和const 在相同的作用域内,只能声明一次
function func(arg) {
let arg; // 报错
}
function func(arg) {
{
let arg; // 不报错
}
}
let const 声明的全局变量不会挂在顶层的对象下面:
- 1、 浏览器的环境的顶层的对象是:window
- 2、 node环境下的顶层对象是 global
- 3、 var声明的全局变量会挂在顶层对象下面,而let,const不会挂在顶层对象下面,
var a = 1;
// 如果在 Node环境,可以写成 global.a
// 或者采用通用方法,写成 this.a
window.a // 1
let b = 1;
window.b // undefined
const
1、 一但声明,必须马上来赋值
let p; var p1; // 不报错
const p3 = '马上赋值'
const p3; // 报错 没有赋;
2、 const 声明赋值不能改变:
const num = '不能改变'
num = '报错'
复杂类型:变量指针不能改变:
const p = ['不能改动']
const p2 = {
name: 'OBKoro1'
}
p[0] = '不报错'
p2.name = '不报错'
p = ['报错']
p2 = {
name: '报错'
}
- 变量指针的那个内存地址所保存的数据不能改动
- 简单类型(number,String,boolean):内存地址就是值,即常量(变量改变就会报错)
- 复杂类型(对象,数组):地址保存的是一个指针,const只能保存指针是固定的(总是指向同一个地址),他的内部值是可以改变的(不要以为const就很安全)
let 和const的使用场景:
1、 let 使用场景:变量,用以替代var
2、 const 使用场景:常量,声明的匿名函数,箭头函数