关于函数高级(含小部分基础)

目录

函数基础

函数的声明和调用

函数的参数

函数的作用域和预解析

函数的返回值

函数高级 

回调函数

匿名函数

闭包函数

递归函数

防抖和节流函数


 

函数基础

  • 函数的声明和调用

    • function 函数名(){} 函数名()

    • var 变量名 = function(){} 变量名()

  • 函数的参数

    • 形参实参系统

    • arguments:实参列表 是一个伪数组 包含函数中接收到的所有实参 这些实参 会作为数组项存在

      • 用于:函数的参数个数 不确定的情况下

  • 函数的作用域和预解析

    • 作用域:变量生效的代码空间

    • 分类

      • 全局作用域:script直接包裹的代码空间 如果是外部引入的js文件 整个js文件就是全局作用域

      • 局部作用域:函数的大括号包裹的代码空间

    • 变量的分类

      • 全局变量:声明在全局作用域中的变量 可以在任何位置 使用

      • 局部变量:声明在局部作用域中的变量 只能在当前作用域中使用

    • 预解析:在任意作用域的js代码 开始执行之前 都要进行 预解析 就是查找当前作用域中的 函数 和 变量的声明 并提升到 当前作用域的最顶端

  • 函数的返回值

    • 获取方式:函数调用表达式的值 就是 函数的返回值

      • 函数名() 变量名() 对象名.方法名()

    • 特点

      • 任何函数都有返回值 默认undefined

      • 返回值 只能返回 一个值 多了就报错

      • 返回值 可以打断函数的执行

函数高级 

回调函数

  • 定义:当一个函数a 作为另一个函数b的实参 被传入的时候 我们就说 函数a是回调函数

匿名函数

  • 定义:就是不写函数名的函数

  • 写法:function(){}

  • 注意:匿名函数 多用于 进行赋值 和 回调

  • 如果函数需要单独进行使用 就不能单纯的不加函数名了 因为 会报错

  • 单独使用匿名函数的写法:(function(形参1,形参2,...){ 函数体代码 })

  • 匿名函数的调用

函数调用 同一格式: 函数()
因此匿名函数的调用 就是在函数后面 加()
(function(形参1,形参2,...){ 函数体代码 })()
  • 实参的传递  :匿名函数传实参 和 普通函数 完全相同
  • 匿名函数的返回值 和 普通函数 完全相同
    1.写法相同
    也是return 返回的数据/变量
    2.使用方法也相同
    也是 函数调用表达式的值 就是 函数的返回值
  • 匿名函数的优点 

    • 优点:匿名函数可以在最大限度上 节省内存

    • 原理:带有函数名 或 变量名的函数 在声明出来之后 就会一直存储在计算机内存中(一直占用内存空间) 但匿名函数 在声明出来之后 不存入内存中 而是在 调用匿名函数的时候 才存入内存中 而且 调用结束之后 还会从内存中 将匿名函数清除出去

    • 使用场景:但凡能用 都建议使用

闭包函数

  • 定义:外层函数包裹内层函数 并在内层函数中 使用外层函数里声明的变量 这种函数结构 就是闭包

  • 闭包结构的特点:

  • 闭包结构中 外层函数中 声明的变量 会永久存储在内存中

  • 数据/变量的存储规则

    • 全局变量:会永久保存在内存中

    • 局部变量:在函数调用的时候 将变量存入内存中 待函数调用结束 将变量从内存中清除出去(js的垃圾清理机制)

    • 闭包外层函数中声明的局部变量:永久保存在内存中

  • 闭包的优缺点

    • 优点:闭包外层函数声明的变量 虽然是局部变量 但可以永久存储在内存中 因此 我们可以用它来模拟全局变量 但是又不像全局变量一样 会污染全局环境(挂载到window对象上) 也不会 导致大量的变量名冲突

    • 缺点:正是因为 外层函数中声明的变量会永久保存 因此如果我们不手动清除 就无法将变量清除出内存,这时 如果大量调用闭包函数 就会导致内存中存入大量的变量,消耗内存空间,严重的时候 甚至会导致内存溢出

  • 闭包模拟私有属性

    • 私有属性:

      • 在很多后台编程语言(c、java等)中,都存在私有属性的概念,在这些语言中,对象的属性被分为了两类——公有属性(public) 和 私有属性(private)

        • 公有属性:任何人都可以随意获取和设置其属性值

        • 私有属性:用户看不到,但是程序会给用户提供操作私有属性的方法,用户可以通过方法来对应的操作私有属性

      • 优点:私有属性 限制了用户的操作 用户只能通过开发者 提供的方法 才能操作私有属性 这样就可以保证私有属性 保存的数据的安全性

递归函数

  • 定义:一个函数 在函数体内部 调用自己 就叫做递归函数

  • 注意:递归函数 最重要的事情是 设置递归结束条件 如果忘记设置 将导致死循环

  • 从理解的角度讲 我们可以理解为 递归函数 就是使用函数 进行循环

  • 递归实现数组的快速排序算法

    • 思路:

      • 1.获取到排序数组的中间数组项(这里我们说的中间数组项是相对的)

      • 2.根据中间项 将数组 分为两个数组 一个存放比中间项大的数组项 另一存放比中间项小的数组项

      • 3.将小数组和中间项以及大数组拼接在一起

防抖和节流函数

  • 在js中 有一些效果 其执行频率 极高(例如:鼠标移动事件) 这种效果会大大浪费计算机的cpu资源,给CPU造成很大负担 因此 我们需要优化这些效果

  • 这里介绍两种优化思路 我们这里以鼠标移动事件为例

    • 防抖

      • 防抖这种方式 是一种强硬方式 要求 鼠标移动事件必须间隔我们指定的时间之后 才能进行触发 如果没有等够时间间隔 就移动了鼠标 就一直不触发 直到等够了位置

function debounce(fn,wait){
            var timer = null;
            //这里我们返回的函数 就是要在一会 作为事件处理函数使用的
            return function (){
                clearTimeout(timer);
                timer = setTimeout(fn,wait)
            }
        }

 

  • 防抖 在用户体验的角度来讲 不够优化
    • 节流

      • 在处理高频执行的效果的时候 节流函数的思路是 控制效果执行的频率

      • function throtling(fn,wait){
                    var flag = "能";//声明一个变量 记录本次触发的事件能否执行的状态 假设为能执行。
                    //这里返回的函数 也是一会用来做事件处理函数的
                    return function(){
                        if(flag=="能"){
                            //证明本次触发的事件 我们能执行
                            fn()
                            flag = "不能"
                            //控制频率
                            setTimeout(function(){
                                flag = "能"
                            },wait)
                        }
                    }
                }

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值