js第三天学习整理

作用域:
     1、全局作用域之外,每个函数都会创建自己的作用域,作用域在函数定义时就已经确定了。而不是在函数执行时
     2、函数的作用域时静态的,只要函数定义好就一直存在,且不会发生改变
     
复制代码

image.png

面试题:
var x= 10
function fn(){
    console.log(x)
}
function show(fn){
    var x = 20
    fn()
}
show(fn)  //20
复制代码
var fn = function(){
    console.log(fn)
}
fn()
var obj = {
    fn2: function(){
        console.log(fn2)//报错,es6才存在块级作用域,所以沿着作用域就找到了window所以报错
        console.log(this.fn2)// this就是谁调用了这个函数,this=>obj(duithis的理解比较差)
    }
}
复制代码
闭包

看一段代码:

html代码
<button>测试1<button>
<button>测试1<button>
<button>测试1<button>
js代码
document.getElementsByTagName('button')
for(var i = 0,length = btns.length;i<length;i++){
    var btn = btns[i]
    btn.onclick = function(){        //注册事件 dom(对应下标)元素事件添加 onclick 
        console.log(`这时第${i+1}个 i`)
    }
}

复制代码

进化版

for(var i = 0,length = btns.length;i<length;i++){
    ;(function(i){
        var btn = btns[i]
        btn.onclick = function(){        //注册事件 dom(对应下标)元素事件添加 onclick 
        console.log(`这时第${i+1}个 i`)
    })(i) //i 读取的是 for循环的 i 
}
复制代码
    1、如何产生闭包
    当一个嵌套的内部(子)函数引用了嵌套的外部(父亲)的变量时就产生了闭包。(这是内部函数已经加载)
    2、产生闭包的条件
    函数嵌套
        内部函数引用了外部函数的数据(变量/函数)
复制代码
常见的闭包
    function fn1(){
        var a = 2
        function fun2(){  //函数定义已经被提什么了(函数定义已经被执行)
            a++
            console.log(a)
        }
        return fun2
    }
    var fun3 = fun1()  // fun3指向 fun2 所以 fun2没有成为回收对象
    
    fun3() //3
    fun3() //4
    fun3 = null //闭包死亡  (包含闭包的的函数对象成为垃圾对象) fun3指向的就是 fun2(?????)
复制代码

闭包的作用

         1、使用函数内部的变量在函数执行完后,任然存活在内存中(延长局部变量的生命周期)
         2、让函数外部可以操作(读写)到函数内部的数据(函数/变量)
         
         函数执行完毕之后,函数内部声明的局部变量(一般不存在)如果产生闭包,外部依然有变量指向这个函数。
         函数外部不能直接访问函数内部的局部变量,通过闭包让外部的得到返回函数,
         并给予变量指向(var fun3 = fun1()),没有这个指向fun2()完成执行没有执行就会成为回收对象,
复制代码
闭包的生命周期
         1、产生:在嵌套内部函数定义执行完成时就产生了(是不在调用) 变量声明式恰恰是
         2、死亡:在嵌套的内部函数成为垃圾对象时
         3、 fun3 = null
         
复制代码
自定义JS模块
     1、具有特点功能的js文件
     2、将所有的数据和功能封装在一个函数内部(私有的)对象可以直接访问到属性,所以需要一个函数
     3、只向外暴露一个或n个方法的方法或属性
     4、
           
复制代码
function myModule(){
    var mes = 'tianze'
    
    function doSomething(){
        console.log(`doSomething${mes.toUpperCase}`)
    }
    function doOtherthing(){
        console.log(`doSomething${mes.toLowerCase}`)
    }
    return {
        doSomething :doSomething,  //返回一个对象  对象的俩个属性保存的是俩个方法,通过访问属性去执行方法
        doOtherthing : doOtherthing,
    }
}
复制代码

引用使用

    myModule().doSomething()   //执行函数后才能得到这个对象
    myModule().doOtherthing()
复制代码

第二种方式:

        ;(function(){
            var mes = 'tianze'
            
            function doSomething(){
                console.log(`doSomething${mes.toUpperCase}`)
            }
            function doOtherthing(){
                console.log(`doSomething${mes.toLowerCase}`)
            }
            
            window.moudle= {                 
            //给window添加属性moudle 是一个对象{ 对象俩个属性 指向的俩个 =>function(可以这么理??)}
            //代码压缩
                 doSomething :doSomething, 
                 doOtherthing : doOtherthing,
            } 
        })()
复制代码

引用使用

       moudle.doSomething()
       moudle.doOtherthing()
复制代码

内存溢出
    闭包缺点:函数执行后,函数的局部变量没有释放,占用内存时间过长,容易造成内存泄露。
    解决办法:能不用的情况下尽量不用。

    
复制代码

内存泄漏

    占用的内存没有及时释放,
    内存泄露积累多了就容易导致内存溢出
    常见的内存泄漏:
        (1)意外的全局变量   //=>没有使用 var /let 声明变量
        (2)没有即使的清理定时器和回调函数
        
复制代码

问题:

   var name  = 'The Window'
   var object = {
       name : 'My Object'
       getNameFunc : function(){
           return : function(){
               return: this.name;
           }
       }
   }
   console.log(object.getNameFunc()())
   //这个object.getNameFunc() 执行返回的是一个函数,在全局执行函数 this指向window

 
     
复制代码
var name2  =  'the Window' 
var  object2 = {
    name2 : 'My Object'
    
    getNameFunc : function(){
        var that  = this   //使用that 保存 this =>就是 object2
        return function(){
            return that.name
        }
    }
}
console.log(object2.getNameFunc()())
//My Object    object2.getNameFunc()()执行返回的就是 =>return object2.name
复制代码

这个题目(待解析)

        function fun(n,o){
            console.log(o)
            return {
                fun:function(m){
                    return  fun(m,n)
                }
            }
        }
       var a = fun(0)   //a.fun(1) ;a.fun(2); a.fun(3) //输出结果
       var b = fun(0).fun(1).fun(2).fun(3); //输出结果    
       var c = fun(0).fun(1); c.fun(2); c.fun(3); 输出结果

复制代码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享