JS 的var let const

红叶何时落水

主要记录一下var,let的区别,以及变量声明提升与函数声明提升

var 用于定义一个变量,并且限制了这个变量的作用域

    (function fn() {
        var a = 'fn_var';
        b = 'window_var';
    })()
    console.log(a);//=>undefined
    console.log(b);//=>window_var

没有var而直接定义的变量视为window的一个属性(作用域自动提升到最上层)

let用于定义一个块级变量,并且不会被视为window的属性(即使在最顶层声明)


    for(let i = 0; i < 2; i++) {
        console.log(i);//=>0 1
    }
    console.log(i);//=>i is not defined

花括号内可以调用i,但花括号外便访问不到i了。

简单来说,var作用于一个函数,let作用于一个花括号

变量声明提升

在C语言中,所有的变量一般都会定义在函数开始的部分,全局变量直接定义在函数外。这就保证了,当我们想要调用某一个变量时,它已经被分配了一个地址空间,我们可以立马对这个地址进行操作。这符合单线程的思想。但在JS中,对变量的定义进行了优化。

    console.log(a);//=>a = undefined,但a是存在的
    var a = 1;
    console.log(a);//=>1
//等同于
    var a = undefined;
    console.log(a);//=>undefined
    a = 1;
    console.log(a);//=>1

所有变量的定义在程序逻辑进行前,都会提升到作用域的顶部;注意,赋值操作不会被提升。

与此同时let声明不会被提升

    console.log(a);//=>Error undefined,a是不存在的
    let a = 1;
    console.log(a);//=>1

在者,在同一个作用域中,var可以多次声明同一个变量,let不可以。


    let a = 1;
    let a = 3;//=>Identifier 'a' has already been declared

    var a = 1;
    var a = 2;
    console.log(a);//=>2

那let的意义何在?

    for (var i = 0; i < 5; ++i) {
        setTimeout(() => console.log(i), 0)//=>5 5 5 5 5 
    }

    for (let i = 0; i < 5; ++i) {
        setTimeout(() => console.log(i), 0)//=>0 1 2 3 4 
    }

异步操作会在主线程都执行完了之后才进行处理,这时i地址里储存的都是最后一个值

而let变量声明不会被提升,且作用域为块级的特点,让第二个循环可以多次分配i的地址,即循环5次,就定义了5次i,并且i的地址都不同。

简单提一下 setTimeout的原理

程序运行到 setTimeout的时候, setTimeout开始计时,然后程序继续向下运行。之后主程序所有的同步任务执行完毕。开始处理异步任务。而异步任务在计时完毕后,会将第一个参数的函数以队列的方式进入到主程序。主程序开始处理它。

关于setInterval它会多出一个判定,判断一下上次的任务有没有搞完,没搞完,就不添加新任务,以此来确保任务进入队列的间隔都是相同时间。注意是进入队列的间隔,而不是1号函数执行完,2号函数开始执行的间隔。想实现后一种效果可以用setTimeout重写一下。

再有setTimeout(()=> {}, 0);并不是真的0,会有一定延时,4ns?

clearInterval会取消计时任务。

回到正题,函数声明的提升

fn();//=>fn
    function fn() {
        console.log('fn');
    }

没有任何问题,并且函数内部的内容也会被一同提升。

突发奇想

    fn();//=>fn is not defined
    (function fn() {
        console.log('fn');
    })()

为圣莫?因为这是一个表达式,不是一个函数。没有分配地址。那么其他地方自然访问了个寂寞。

而且他没有返回值

    console.log(1+function fn() {
        console.log('fn');
    }())//=>1 + undefined = NaN

再有,函数提升的优先级在变量之前

    fn();//=>undefined
    var a = 1;
    function fn() {
        console.log(a);
    }
    //等同于
    function fn() {
        console.log(a);
    }
    var a = undefined;
    fn();
    a = 1;

另外函数名字与变量名字是相互冲突的,这得益于JS的弱语言类型。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

红叶落水

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值