JavaScript函数进阶回调函数递归函数闭包函数

Posted 别Null.了

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript函数进阶回调函数递归函数闭包函数相关的知识,希望对你有一定的参考价值。

目录

一、函数进阶

函数表达式(匿名函数)

函数的内置对象

二、回调函数

实例

三、递归函数

递归的使用前提

递归过程

递归练习

练习一 使用递归函数,计算斐波拉契数列的前20项

四、变量的作用域

作用域的分类

作用域链

五、闭包函数

主要用途:

闭包函数的实现

六、预解析


一、函数进阶

函数表达式(匿名函数)

函数表达式是将声明的函数赋值给一个变量,通过变量完成函数的调用和参数的传递。函数表达式的定义必须在调用前。

var sum = function(num1,num2){    //函数表达式
   return num1+num2
}
console.log(sum(1,2))   //调用函数,输出结果:3

函数的内置对象

arguments是一个对应于传递给函数的参数的类数组对象。是函数的内置对象,保存了函数接收的所有实参。arguments是以数组的方式存放所有。(具体使用在上一篇文章讲到)

二、回调函数

回调函数指的就是一个函数A作为参数传递给一个函数B,然后在B的函数体内调用函数A。此时,称函数A为回调函数。

可以这样理解:比如我们有3个函数A,B,C,一个主函数里面有一个功能函数,功能函数需要用到A时就会调用A,当它需要用B时就要删掉A再调用B,这样就会很麻烦。因此我们将函数A,B,C当做参数,在每次功能函数需要时以参数形式进行传递,功能函数可以通过修改参数来调用不同的函数,而其本身不用做修改。我们称A,B,C为回调函数

实例

//定义主函数,回调函数作为参数
function A(fun) 
{
    fun();  
    console.log('我是主函数')     
}

//定义回调函数
function B()
{
    console.log('我是回调函数')
}

//调用主函数,将函数B传进去
A(B)

//输出结果
//我是回调函数
//我是主函数

三、递归函数

递归调用指的是一个函数在其函数体内调用自身的过程,这种函数称为递归函数。

递归的使用前提

  • 问题可以分解(即复杂的问题逐步分解成简单的问题)
  • 分解得到的新问题的解法与原来老问题的解法是相同的
  • 必须有明确的终止条件

递归过程

  • 自上而下分解问题
  • 自下而上回溯得到问题的解

递归练习

练习一 使用递归函数,计算斐波拉契数列的前20项

//函数的声明
function fun(n)
{
    if(n==1||n==2){   //斐波那切数列前两项都为1
        return 1
    }
    return fun(n-2)+fun(n-1)   //从第3项开始每一项都是前两项和
}
//函数的调用(递归)
<script>
    var str = ''
    for(var i=1;i<=20;i++)
    { 
       //fun(i)    //调用函数fun()
       str = str +fun(i)+'\\t'   //让数列在一行输出
    }
    console.log(str)
</script>

四、变量的作用域

变量需要在它的作用范围内才可以被使用,这个作用范围称为变量的作用域。

作用域的分类

javascript根据作用域使用范围的不同,划分如下:

  • 全局变量:不在任何函数内声明的变量(显式定义)或在函数内部省略var声明的变量(隐式定义)都称为全局变量。(在浏览器页面关闭后才会销毁,比较占空间)
  • 局部变量:在函数体内利用var关键字定义的变量称为局部变量。(在函数调用结束后就销毁,比较节省内存资源)
  • 块级变量:ES6提供的let关键字声明的变量称为块级变量。(当语句块结束后就销毁)

定义局部变量时,当省略var关键字时,如果变量在当前作用域下不存在,会自动向上级作用域查找变量。

作用域链

当在一个函数内部声明另一个函数时,内层函数只能在外层函数的作用域内执行,在内层函数执行的过程中,若需要引入某个变量,首先会在当前作用域中寻找,若未找到则继续向上一级的作用域中寻找,直到全局作用域,称这种链式的查询关系为作用域链。

五、闭包函数

有权访问另一函数作用域内变量(局部变量)的函数

主要用途:

  • 可以在函数外部读取函数内部的变量
  • 可以让变量的值始终保持在内存中

注意:由于闭包会使得函数中的变量一直被保存在内存中,内存消耗很大,所以闭包的滥用可能会降低程序的处理速度,造成内存消耗等问题

闭包函数的实现

闭包的常见创建方法就是在一个函数内部创建另一个函数,通过另一个函数访问这个函数的局部变量可以在函数外部读取函数内部的变量。

实例

function fn()
{
   var times = 0
   var c = function()   //相当于闭包函数(在函数内部定义)
   {
      return ++times
    }
    return c
}
var count = fn()   //保存fn()返回的函数,count就是一个闭包
console.log(count())   //输出结果:1
console.log(count())   //输出结果:2
console.log(count())   //输出结果:3

六、预解析

JavaScript解析器在运行JavaScript代码的时候会进行预解析,也就是提前对代码中的var变量声明和function函数进行预解析。

var可以进行预解析,let不会进行预解析。

实例

console.log(num)    //输出结果:undefined
var num = 10
console.log(num2)   //报错,提示num2 is not defined

//var预解析
var num
//undefined
console.log(num)
num = 10

 

以上是关于JavaScript函数进阶回调函数递归函数闭包函数的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript函数进阶及作用域

闭包和递归 丨JavaScript 函数进阶

前端(十三)—— JavaScript高级:回调函数闭包循环绑定面向对象定时器

JavaScript 函数进阶函数(匿名回调递归函数)及相关练习

JavaScript函数函数进阶作用域及预解析

JavaScript-函数(调用参数returnarguments匿名回调递归函数)函数案例