0
点赞
收藏
分享

微信扫一扫

学习web第4天

爱动漫建模 2022-02-17 阅读 45

变量,作用域和内存问题
全局变量:全局变量定义可以提供所有代码块和函数调用
私有变量:在js下,只有函数里定义的变量才是私有的
基本数据类型:null,undefined,number,string,Boolean
引用数据类型:object,

变量提升和作用域
预解释(变量提升)
    在当前的作用域中,js代码执行之前,浏览器首先会把var和function的声明内容,进行提前声明或定义
    声明和定义的区别
        var a //声明:告知浏览器在内存中存储一个变量
        var b=11 //定义:不但定义了变量,还进行了赋值
    变量提升的函数和变量的区别
    var在内存中只完成了声明,function在内存中完成了声明和定义,只是函数没调用的时候存储的是字符串
    例如:
    console.log(a)//输出 undefined
    var a=11
    fun()//执行函数
    function fun(){
        console.log("这是函数")
    }

变量提升注意事项
    1.不定义var的区别
        console.log(a)//输出undefined
        console.log(b)//报错,没有变量提升的过程
        var a=11
        b=22
    2.不管条件是否成立,都要进行变量提升
        console.log(a)//输出undefined,变量还存在
        if(false){
            var a=12
        }
    3.当执行一个匿名函数的时候,是不进行预解释的,代码的执行和定义一起完成了
        (function(){
            var a=b=3//var b=3 a=b
        })()
        console.log(a)//3 b变量提升了
        console.log(b)//报错 a没有变量提升
    4.当函数里的return语句执行时,下面的语句虽然不执行,但是也需要变量提升
        注意:函数作用域下,有私有变量找私有变量,没有形参,形参没有找全局,但是如果形参和私有变量进行了变量提升,就不会找全局变量了
        function fun(){
            console.log(a)
            return false
            var a=66
        }
        fun()
    5.在js中,变量和函数名称重复,也冲突,在变量提升时,如果名称声明过了,不会再次声明,但是可以重新赋值
        function num(){
            console.log(111)
        }
        num()
        var num=66
        console.log(num)//输出66,var不会重新声明,但是可以改变值
        num()//报错

垃圾回收
    js具有自动垃圾回收机制,无需手动清除
    标记清除
        原理:当js函数中声明一个变量,将变量标记为“进入环境”,则变量在内存中占有位置,当变量执行完毕,会将其标记为“离开环境”,js垃圾回收机制检测到“离开环境”,就会自动回收
        在标准浏览器下常用这种回收方式,只是时间间隔不一样
    引用计数
        原理:js会跟踪每一个变量的引用次数,当变量被声明并将一个值赋给变量,则引用计数会标注为1,如果变量执行运算或又进行了赋值,则引用计数进行加1,相反,变量赋给其他变量,或者没再进行操作,则次数减1,直到次数变成0,则回收销毁
        如果出现循环引用,a调用b,b也调用a,则内存会一直没有释放,容易出现内存泄漏
    内存泄漏和内存溢出的区别
        内存泄漏:动态给内存分配空间,在使用完毕之后,没有进行释放,导致一直占着内存,直到程序结束

        内存溢出:不顾堆栈分配的数据大小,向内存写入过多的数据,导致数据越界
    栈和堆的销毁方式
        栈内存
            全局变量:只有浏览器关闭的时候,才会回收
            局部变量:只有定义在函数里的才是局部变量,函数会产生自己的作用域,当函数执行完毕时,js内存机制会自动进行释放
        堆内存
            对象或函数在堆内存开辟空间,堆内存就会生成一个引用地址,如果有代码引用了这个地址,则对象不会被销毁。如果想销毁,需要把引用设置成null即可。
            例如:
            var x = new Array()
            x=null //销毁了
        不被销毁的特殊情况
        1.函数执行时,返回了一个对象,并在函数外调用,那么私有变量不会被销毁
            function fun(){//延长作用域链
                var x=[1,2,3]
                return x
            }
            var arr=fun()
            console.log(arr)//数组可以在函数访问,不被销毁
        2.在一个私有作用域中,给dom元素绑定事件,这个私有作用域不会被销毁
            var btn=document.getElementByld("btn")
            btn.οnclick=function(){
                var num=11
                alert(num)
            }
        3.闭包(特殊作用域)
            闭包是能够有权访问其他函数内部的私有变量的函数,可以理解为函数嵌套函数,必须满足以下特点,缺一不可:
                1.函数嵌套函数
                2.内部函数访问外部函数的变量
                3.变量不会被垃圾机制所回收
            例如:
                function fun(){
                    var a=11
                    return function(){
                        var b=1
                        return ++a+(++b)
                    }
                }
                var f=fun()
                var v2=f()
                console.log(v2)//输出14
                var v3=f()
                console.log(v3)//输出15

            注意:fun只执行一次,a不被销毁,闭包执行多选,b每次执行·都重新赋值成了1
            闭包的作用
            1.可以模拟私有方法
            2.用来实现对象的封装
            3.用闭包可以访问缓存,当代码执行时间过长,可以先从缓存中读取

举报

相关推荐

0 条评论