二、let进阶、const、全部变量与顶层对象

二、let进阶、const、全部变量与顶层对象

一、let进阶

let创建了块级作用域,每次循环时内部的块级作用域都会去访问外层块级作用域中的变量i,而外层块级作用域中的变量i都不同,所以打印0-9;类似于闭包:内部函数返回到外部,保持其作用域链不释放。

var arr = [];
for(let i = 0; i < 10; i++){
    arr[i] = function(){
        console.log(i);
    }
}
for(var j = 0; j < 10; j++){
    arr[j]();
}

函数声明提升只在当前块级作用域内,不像var声明提升是作用域中逐级提升的。

但是不推荐在块级作用域中声明函数——>使用函数表达式。

{
    let a = 1;
    {
        // 函数声明提升只会在当前块级作用域内
        a(); // 10
        function a(){
            console.log(10);
        }
    }
    console.log(a); // 1
}

二、const

结论先行:const同样可以创建(产生)块级作用域。

2.1 ※const声明时必须赋值,且值不可改变(常量)

const声明了一个引用类型的值,只能保证栈中的引用值的地址不改变,而堆中的引用值本身是可以被修改的。

------>解决方案:Object.freeze()方法可以冻结一个对象。一个被冻结的对象再也不能被修改;冻结了一个对象则不能向这个对象添加新的属性,不能删除已有属性。

const obj = {
    name: 'white'
}
// 对象冻结后,无法修改/增加对象的属性值
Object.freeze(obj);
obj.name = 'he';
obj.age = 22;
console.log(obj); // {name: 'white'}

------>但是如果引用值的属性仍然为引用值,仍可以改变引用值内部引用值的值

// 若对象的属性值为一个引用类型的值呢?
const obj1 = {
    friends: {
        name: 'white',
        fav: 'basketball'
    }
}
Object.freeze(obj1);
obj1.friends.name = 'jake';
console.log(obj1);

在这里插入图片描述

------->解决方案:循环冻结

const obj1 = {
    friends: {
        name: 'white',
        fav: 'basketball'
    }
}
myFreeze(obj1);
obj1.friends.name = 'jake';
console.log(obj1);

function myFreeze(obj){
    Object.freeze(obj);
    // 遍历对象属性
    for(var key in obj){
        if(typeof(obj[key]) === 'object' && obj[key] != null){
            myFreeze(obj[key]);
        }
    }
}

在这里插入图片描述

但很少用,源头上解决这个问题:

const http = require('http');

定义模块时,最后一步return实例化对象,不会(不允许)对父级构造器进行修改。

2.2 const不会声明提升,会产生一个暂时性死区

2.3 const只能在当前作用域下生效

2.4 const在同一作用域下不可重复声明

三、全局变量与顶层对象

浏览器环境中顶层对象是window。

var function定义的全局变量的值与顶层对象window的同名属性值相同。

var a = 2;
//当我修改变量时,名字写错了,但 window 的属性值仍能访问到,不合理
b = 1;
console.log(window.b); // 1

而let、const定义的全局变量与在顶层对象window上找不动同名属性。

注:不同环境中顶层对象不同;

浏览器:window;

node:global。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值