ES6的const和let

本文详细介绍了ES6中的块级作用域概念及其特性,包括let与const声明的变量行为,以及在不同环境中声明函数的行为差异。通过具体示例展示了变量提升、暂时性死区等问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

let x = ‘global’
{
console.log(x)
let x = 1; //let不能变量提升
}

var bar = 12;
{
console.log(bar);//暂时性死区:根据变量不能提升,变量由let声明,在声明之前都是死区,用就会报错(赶脚和变量不提升也有关系)
let bar = 13;
}

{
var a = 1;
var a = 2;//var 可以这样声明两个同样名字的变量
}
{
let a = 1;
let a = 2;//let 不可以
//---------------------
let b = 1;
var b = 2;//这样也不可以
}

let count = 1;
function fun(){
console.log(count);
if(true){
let count = 3;
}
}
fun();//1
var count = 1;
var aa = 3;
function fun(){
console.log(count);//这里的count拿的是下面的count,看来在函数作用域里,先找的是内部的变量,内部没有再找外部的变量
if(true){
var count = 3;
var aa = 2;
}
console.log(aa);//2
}
fun();//undefinde
for (var i = 0; i < 5; i++) {

}
console.log(i);//5 泄漏成为了全局作用域

/*上面的两个例子,说明了块级作用域的重要行
一个是函数内部的变量覆盖了外部变量
一个是循环体内的i 泄漏成为了全局作用域

ES5规定,函数只能在顶层作用域和函数作用域之中声明,不能在块级作用域声明。
但是,浏览器没有遵守这个规定,为了兼容以前的旧代码,还是支持在块级作用域之中声明函数,因此上面两种情况实际上都能运行,并不会报错。

ES6引入了块级作用域,明确允许在块级作用域之中声明函数。ES6规定,在块级作用域之中,函数声明语句的行为类似于let,在块级作用域之外不可引用。
/
function fun (){
console.log(‘外面的’);
}
(function (){
if(true){
function fun(){
console.log(‘里面的’);
}
}
fun()
})();
/

在es5浏览器中运行的话,应该得到的是 里面的 (函数整个提升到头部),
在es6浏览器中运行的话,得到的是 外面的(理论上),但是实际上,会报错(声明提升了,函数没有提升)
允许在块级作用域内声明函数。·
函数声明类似于var,即会提升到全局作用域或函数作用域的头部。
·同时,函数声明还会提升到所在的块级作用域的头部。
上面的规则只针对es6浏览器的,其他的浏览器按照let去处理
不同的环境的行为差异过大,所以应该避免使用块级作用域里使用函数,如果需要,写成函数表达式
/
let f = function(){
return ‘外部的’;
};
(function (){
if(true){
let f = function(){
return ‘内部的’;
};
}
console.log(f());//外部的
})()//函数表达式。let
/
*
块级作用域本质上,块级作用域是一个语句,将多个操作封装在一起,没有返回值。
do表达式可以让块级作用域变成表达式,即可以有返回值了
/
let x = do {
let s = 1;
s;
};
console.log(x); // 这是个es6的提案,所以现在没办法用
/
*
const命令(用大写字母表示变量名)

const命令,声明必须初始化
并且初始化之后不能改变值
const的作用域与let命令相同:只在声明所在的块级作用域内有效。
不会变量提升,有暂时性死区,不能重复声明
const实际上保证的并不是变量的值不得改动,而是变量指向的那个内存地址不得改动。
对于简单类型的数据(数值、字符串、布尔值)而言,值就保存在变量指向的内存地址中,因此等同于常量。
但对于复合类型的数据(主要是对象和数组)而言,变量指向的内存地址保存的只是一个指针,(对象可以扩展,但是指针不能变)
const只能保证这个指针是固定的,至于它指向的数据结构是不是可变的,这完全不能控制。
因此,将一个对象声明为常量时必须非常小心。
*/
const MAX = 3;
console.log(MAX);
MAX = 4; // “MAX” is read-only
console.log(MAX);
const obj = {};
obj.aa = 1;
obj = {bb:2};//这里就不能把一个对象赋值给obj,这样就改变了指针,array也一样
console.log(obj);
const foo = {a: {b: 2, c: {d: 4}},e:[1,5,3]};
console.log(Object.keys(foo))
let freezeObj = (obj) => {//深度冻结对象
Object.freeze(obj);
Object.keys(obj).forEach((key, i) => {
if(typeof obj[key] === ‘object’) {
freezeObj(obj[key]);
}
})
}

freezeObj(foo);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值