Day07-JS高级编程

Day02-JS高级编程

一、闭包(扩展)

概念:闭包指的就是在子函数中,可以访问父级函数中的变量。闭包形成的条件,需要在一个函数中嵌套一个子函数,内部函数访问外部函数的变量。

案例1-闭包的基础

        /**
         * 函数声明
        */
        function fun(){
            var name = "hello" 
            return function(){
                console.log(name);
            }
        }    

        //外部函数调用,外部函数执行完后,函数的代码会从栈内存中销毁
        let fun2 = fun()
        // console.log(fun2);
        //调用子函数
        fun2()

fun()调用完成后,fun这个函数会从内存中清除。

变量name会存放在闭包空间里面。

当调用内部函数fun2(),name使用完,闭包空间里面对应name消失

案例2

如下代码输出的结果都是一样的

    <script>
        
        /**
         * 页面打开,for循环会立马执行,会创建5个延时器
         * 延时器在定时时间到了才会执行
         * 
         * 循环执行完后,i的值已经是5了,又过了5秒延时器开始执行,延时器要输出变量i,会输出变量i的最终结果
        */
        for(var i=0;i<5;i++){
            setTimeout(() => {
                console.log("-------",i);
            }, 5000);
        }
    </script>

使用闭包解决这个问题

    <script>
        
        /**
         * 页面打开,for循环会立马执行,会创建5个延时器
         * 延时器在定时时间到了才会执行
         * 
         * 循环执行完后,i的值已经是5了,又过了5秒延时器开始执行,延时器要输出变量i,会输出变量i的最终结果
        */
        for(var i=0;i<5;i++){
            //立即执行函数作为父级函数,index是父级函数的变量
            (function(index){
                //延时器中的函数作为子函数,
                setTimeout(() => {
                    console.log("-------",index);
                }, 5000);

            })(i)
        }
    </script>

案例3

如下代码输出的结果都是一样的

    <script>
        //数组里面可以存储任何数据,包括对象,函数等
        var arr = []
        for(var j=0;j<5;j++){
            arr.push(function(){
                console.log(j);
            })
        }

        arr[0]()
        arr[1]()
        arr[2]()
        arr[3]()
        arr[4]()

    </script>

使用闭包解决这个问题

    <script>
        //数组里面可以存储任何数据,包括对象,函数等
        var arr = []
        for(var j=0;j<5;j++){
            (function(index){
                arr.push(function(){
                    console.log(index);
                })
            })(j)
            
        }

        arr[0]()
        arr[1]()
        arr[2]()
        arr[3]()
        arr[4]()

    </script>

总结

​ 闭包属于了解性知识点

​ 在ES5中闭包用的比较多,在ES6中使用let创建变量来代替闭包这个知识

二、内存空间讲解

基本数据类型: 字符串 数字 布尔 undefined null

引用数据类型: 数组 对象 函数

案例1
    <script>
        /**
         * 基本数据类型
        */
        let a1 = 100
        let a2 = a1
        //修改变量a1的值为200
        a1 = 200
        console.log("a1=",a1);
        console.log("a2=",a2);

        console.log("-------------------");
        /**
         * 引用数据类型
        */
        let arr1 = [1,2,3]
        let arr2 = arr1
        //修改数组arr1中下标为0的元素,修改成300
        arr1[0] = 300
        console.log("arr1=",arr1);
        console.log("arr2=",arr2);
    </script>

image-20230602145511386

案例2

image-20230602152217800

上下文

代码在执行过程中会有两种上下文对象

  1. 全局上下文:打开浏览器时,内存里面就有产生一个全局上下文(window),当浏览器关闭,全局上下文就销毁。
  2. 函数上下文:当函数被调用的时候,产生一个函数上下文对象,函数调用结束,这个函数上下文对象就会消失。

三、对象的拷贝

对象拷贝:将程序中的对象,克隆一份新的(一模一样的)出来。

分类:

  1. 浅拷贝:浅拷贝指的就是在拷贝对象的时候,只考虑最外层的地址。不考虑对象内部还有对象这种情况
  2. 深拷贝:一个复杂对象,都要产生一个新的。

浅拷贝

1 拷贝数组
let arr1 = [1,2,3]
let arr2 = [...arr1] // 会得到一个新的数组,跟原数组的数据一模一样
2 拷贝对象
let obj1 = {name:"赵日天",age:200}
let obj2 = {...obj1} // 会得到一个新的镀锌,跟原对象的数据一模一样

注意:

​ 扩展运算符可以直接扩展数组,但是不能直接扩展对象

​ 使用扩展运算符扩展对象的时候,必须使用{}包裹

深拷贝

     <script>
        let obj1 = {
            name:"李杀神",
            age:20,
            school:{name:"华师一附中",className:"一年级一班"},
            hobby:["琴","琪","诗","画"]
        }

        /**
         * 对象的深拷贝
         * 1.把被拷贝的对象转成json字符串
         * 2.把json字符串再转成js对象
        */
        let obj2 = JSON.parse(JSON.stringify(obj1))
 
        //修改obj1
        obj1.name = "王诛魔"
        obj1.school.name="武汉第一中学"
        obj1.hobby[2] = "书"

        //通过比较内存地址,判断obj1跟obj2是否是同一个对象
        console.log(obj1 == obj2);
        console.log(obj1);
        console.log(obj2);
     </script>

四、函数柯里化

基础概念

概念:将多个参数的函数变成单一参数的函数,嵌套返回所有的参数运算后的最终结果.

简单来说:柯里化就是一个函数变化的过程,指的是将一个函数fn(a,b,c)变成fn(a)(b)(c),

累加的一个案例:

function sum1(a,b,c){
	return a + b + c
}
let r1 = sum1(1,2,3)
console.log(r1);

函数柯里化后结果

        function sum2(a){
            return function(b){
                return function(c){
                    return a+b+c
                }
            }
        }    

        // let fun1 = sum2(1)
        // let fun2 = fun1(2)
        // let result = fun2(3)
        // console.log(result);
        let result = sum2(1)(2)(3)
        console.log(result);

总结:函数柯里化并没有引入新的内容,只是在原来函数基础上针对多参数变成单个参数.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值