• var的变量提升和let的


    //es3/es5
        //变量提升:当栈内存(作用域)形成,JS代码自上而下执行之前,浏览器首先会把所有带var和function关键字的进行提前的
        //声明或定义.这种预先处理机制称之为变量提升。
        //声明(declare):var a或function sum 
        //定义(defined):a=12 也就是赋值
        //变量提升阶段:
        //带var的只声明未定义
    console.log(a)//undefined
        var a = 12;
        function b(arr){//变量提升阶段function就完成了声明和赋值,浏览器会在全局作用域声明一个b,然后再形成一个堆内存里面
            //是函数体里面的代码字符串。这个堆内存会有一个16进制的地址,而全局里面声明的那个b就会指向这个地址
            //因为函数在变量提升阶段就完成了声明和赋值,所以在代码执行阶段在遇到b这个函数就不会在重复声明赋值,就会直接跳过
            for(let i=0;i<arr.length;i++){
                console.log(i)
            }
        }
        //跳过后就会执行下面这个函数调用,传了一个数组进去。
        //而执行一个函数也就是形成了一个私有栈内存。当私有的作用域形成后也不是立即代码执行,而是先进行变量提升(变量提升前,先形参赋值)
        b([1,2,3,4])
        //在ES3和ES5语法规范中,只有全局作用域和函数执行的私有作用域(栈内存),其他大括号不会形成栈内存
    //带var与不带var
        //在全局作用域下声明一个变量,也相当于给window全局对象设置了一个属性,变量的值就是属性值(私有作用域下声明的私有变量
        //和window没有关系)
        //带function的声明和赋值都完成了
        //变量提升至发生在当前作用域(例如:开始加载页面的时候支队全局作用域下的进行提升,因为此时函数中存储的都是字符串)
        //在全局作用域先声明的函数或者变量是‘全局变量’,同理,在私有作用域下声明的变量是‘私有变量’[带var和function才是声明
    console.log(i)//undefined
        console.log(window.i)//undefined
        console.log('i' in window)//true   在变量提升阶段,在全局作用域中声明了一个变量i,此时就已经把i当做属性值赋值
        //给了window了,只不过此时还没有给i赋值,默认是undefined  
        // in? :检测某个属性是否隶属于这个对象
        var i = 9//变量值修改window的值也跟着修改
        console.log(i)//9
        console.log(window.i)//9  window的一个属性名为i
        i=13
        console.log(window.i)//13
        window.i=14
        console.log(i)//14    重点:全局变量和window的属性存在‘映射机制’,就是有一个改变另一个也跟着改变
    //不带var     不带var的本质是window的属性
        //console.log(j)//j is not defined   这里的J是按照变量的来识别的
        //console.log(window.j)//undefined    这里是按照window的属性来识别的,因为对象没有某一个属性返回的就是undefined
        //console.log(window.j)//false 不存在这个属性
        j=10// 这里不带var 就相当于给window加了一个属性叫j,值是10
        console.log(j)//10
        console.log(window.a)//12
    
        // var q =10,
        //     s =11 //这样写s是带var
        // var q = s =11 // 这样写不带var  
        //在私有作用域中带var和不带var也有区别:带var在私有作用域变量提升阶段都声明为私有变量和外界没有任何关系
        //不带var 不是私有变量,它会想它的上级作用域查找,看它是否是上级的变量,不是继续向上查找,一直找到window为止
        //这种查找机制叫‘作用域链’
        //console.log(n,m)//undefined undefined
        var n =13;
            m =13;
        function fn(){
            console.log(n,m)//变量提升阶段先var了一个n所以是 undefined 但是m不带var,向上级查找所以m是13  ;
            var n = m = 14//此时都是14
            console.log(n,m)//14 14
        }
        fn()
        console.log(a,m)// 这里的a是全局的所以是13,b在函数里被重新赋值所以是14
    //在私有作用域中如果向上级查找变量到window的时候发现window也没有这个属性时又是怎么做的呢?
    function f(){
            b = 13
            console.log('b' in window)//true  在作用域查找的过程中,如果找到window也没有这个变量,相当于给window设置了
            //了一个属性b
            console.log(b)//13
        }
        f()
        console.log(b)//13
    //只对等于号左边进行变量提升
    fnn()// fnn is not a function 
        sun()//2 
        var fnn = function (){//函数表达式声明 因为是用var关键字声明在变量提升阶段只提升了等号左边的fnn,
            //但是并没有定义或赋值,所以在上面调用时报错
            console.log(1)
        }
        fnn()
        function sun (){//普通方式声明的函数在 变量提升阶段就已经声明和定义完毕 所以上面可以直接执行
            console.log(2)
        }
        sun()
    //条件判断下变量提升
    console.log(z)
        if(1===2){//在当前作用域下,不管条件是否成功都要进行变量提升,
            //带var的还是只是声明
            //带function的在老版本浏览器渲染机制下,声明+定义都处理,但是为了迎合es6中的块级作用域,新版浏览器对于函数
            //(在条件判断中的函数),不管条件是否成立,都是先声明,没有赋值。
            var z = 10
        }
        console.log(z)
    
        if(1===1){
            console.log(fs)//函数本身:当条件成立,进入到判断体中(ES6中它是以个块级作用域)第一件事并不是变量提升,
            //先把fs声明并定义,也就是判断体中代买执行前,fs就已经赋值了
            function fs(){
                console.log('ok')
            }
        }
        console.log(fs)//函数本身
    //ES6中let创建的变量不存在变量提升。不允许重复定义  暂时性死区
        //切断了全局变量和window属性的映射机制
    console.log(a)//a is not defined
        let a =12
        console.log(window.a)//undefined
        console/log(a)//12
  • 相关阅读:
    dotnet 控制台读写 Sqlite 提示 no such table 找不到文件
    dotnet 控制台读写 Sqlite 提示 no such table 找不到文件
    dotnet 控制台 Hangfire 后台定时任务
    dotnet 控制台 Hangfire 后台定时任务
    dotnet 获取指定进程的输入命令行
    dotnet 获取指定进程的输入命令行
    PHP sqrt() 函数
    PHP sinh() 函数
    PHP sin() 函数
    PHP round() 函数
  • 原文地址:https://www.cnblogs.com/menggege/p/14184504.html
Copyright © 2020-2023  润新知