zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    mongodb 3.4复制搭建
    mongodb 用户管理
    mongodb 3.4 TAR包启动多个实例
    mongodb 3.4 YUM安装
    mongodb数据库备份恢复-windows系统
    mongodb数据库索引管理
    mongodb数据库集合操作
    Unity3d 实现鼠标左键点击地形使角色移动到指定地点[脚本]
    Unity3D性能优化之Draw Call Batching
    Unity3D占用内存太大怎么解决呢?
  • 原文地址:https://www.cnblogs.com/menggege/p/14184504.html
Copyright © 2011-2022 走看看