06_JavaScript函数的基本使用-函数递归

导读:本篇文章讲解 06_JavaScript函数的基本使用-函数递归,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

认识函数

  • 什么是函数呢?
  • 目前, 我们已经接触过几个函数了
    • alert函数:
      • 浏览器弹出一个弹窗
    • prompt函数:
      • 在浏览器弹窗中接收用户的输入
    • console.log函数:
      • 在控制台输入内容
    • String/Number/Boolean函数等
  • 当我们在谈函数时, 到底在谈些什么?
    • 函数其实就是某段代码的封装,这段代码帮助我们完成某一个功能
    • 默认情况下JavaScript引擎或者浏览器会给我们提供一些已经实现好的函数
    • 我们也可以编写属于自己的函数;

函数使用的步骤

  • 函数的使用包含两个步骤
    • 声明函数 —— 封装 独立的功能
    • 调用函数 —— 享受 封装 的成果
  • 声明函数,在JavaScript中也可以称为定义函数
  • 声明函数的过程是对某些功能的封装过程
  • 在之后的开发中,我们会根据自己的需求定义很多自己的函数
  • 调用函数,也可以称为函数调用
  • 调用函数是让已存在的函数为我们所用
  • 这些函数可以是刚刚自己封装好的某个功能函数
  • 当然, 我们也可以去使用默认提供的或者其他三方库定义好的函数
  • 函数的作用
    • 在开发程序时,使用函数可以提高编写的效率以及代码的重用

声明和调用函数

  • 声明函数使用function关键字:这种写法称之为函数的定义

    • function 函数名() {
        //函数封装的代码块
      }
      
  • 注意

    • 函数名的命名规则和前面变量名的命名规则是相同的;
    • 函数要尽量做到见名知意(并且函数通常是一些行为(action),所以使用动词会更多一些);
    • 函数定义完后里面的代码是不会执行的,函数必须调用才会执行
  • 调用函数通过**函数名()**即可:比如test()

  • 练习:定义一个函数,函数中计算10和20数字的和,并且打印出结果

  • function sum() {
      var num1 = 10
      var num2 = 20
      var result = num1 + num2
    	console.log(result)
    }
    sum()
    

函数的参数

  • 函数的参数

    • 函数,把 具有独立功能的代码块 组织为一个小模块,在需要的时候 调用
    • 函数的参数,增加函数的 通用性,针对 相同的数据处理逻辑,能够 适应更多的数据
      • 在函数 内部,把参数当做 变量 使用,进行需要的数据处理
      • 函数调用时,按照函数定义的参数顺序,把 希望在函数内部处理的数据通过参数 传递
  • 形参和实参

    • 形参定义 函数时,小括号中的参数,是用来接收参数用的,在函数内部作为变量使用
    • 实参调用 函数时,小括号中的参数,是用来把数据传递到 函数内部 用的
  • 两个参数的函数练习

    • 练习:传入两个数字,计算两个数字的和,并且打印结果

    • function sum(num1, num2) {
        var result = num1 + num2
      	console.log(result)
      }
      sum(10, 20)
      

函数的返回值

  • 回想我们之前使用的prompt函数,函数需要接受参数,并且会返回用户的输入

  • 所以说, 函数不仅仅可以有参数, 也可以有返回值

    • 使用return关键字来返回结果
    • 一旦在函数中执行return操作那么当前函数会终止
    • 如果函数中没有使用 return语句 ,那么函数有默认的返回值:undefined
    • 如果函数使用 return语句,但是return后面没有任何值,那么函数的返回值也是:undefined
  • 练习一:实现一个加法计算器

    • function sum(num1, num2) {
        return num1 + num2
      }
      var result = sum(10, 20)
      console.log(sum)
      
  • 练习二:定义一个函数,传入宽高,计算矩形区域的面积

    • function area(num1, num2) {
        return num1 * num2
      }
      var result = area(20, 30)
      console.log
      
  • 练习三:定义一个函数,传入n(n为正整数),计算1~n数字的和

    • function sumN(n) {
        var total = 0
        for(let i = 1; i <= n; i++) {
          total += i
        }
        return total
      }
      var result = sumN(5)
      console.log(result)
      

实战函数练习

  • 传入一个数字,可以根据数字转化成显示为 亿、万文字显示的文本

    • //数字格式化工具函数封装
      function formatCount(count) {
      	if (count >= 10_0000_0000) {
      		result = Math.floor(count / 1_0000_0000) + "亿";
      	} else if (count >= 10_0000) {
      		result = Math.floor(count / 10_0000) + "万";
      	} else {
      		result = count;
      	}
      	return result;
      }
      console.log(formatCount(549849165131));
      console.log(formatCount(156545612));
      console.log(formatCount(15559));
      

函数中调用函数

  • 在开发中,函数内部是可以调用另外一个函数的

    • function foo() {
        console.log("foo函数被调用")
      }
      function bar() {
        foo()
      }
      bar()
      
  • 既然函数中可以调用另外一个函数,那么函数也可以调用自己

    • 但是函数调用自己必须有结束条件,否则会产生无限调用,造成报错

函数的递归

  • 事实上,函数调用自己还有一个专业的名词,叫做递归

  • 递归是一种重要的编程思想

    • 将一个复杂的任务,转化成可以重复执行的相同任务
  • 案例1:实现一个自己的幂函数pow

    • //for循环实现x的n次幂
      function pow(x, n) {
        var result = 1
        for(let i = 0; i < n; i++) {
          result *= x
        }
        return result
      }
      console.log(pow(2, 3))
      
    • //递归实现x的n次幂
      function pow(x, n) {
        if(n === 1) return x
        return x * pow(x, n-1)
      }
      console.log(pow(2, 3))
      
  • 案例二: 实现斐波那契数列

    • 什么是斐波那契数列

      • 前两项相加等于第三项
      • 数列: 1 1 2 3 5 8 13 21 34 55 … x
      • 位置: 1 2 3 4 5 6 7 8 9 10 … n
    • //for循环实现斐波那契数列 输入位置显示对应的数列
      function foo(n) {
      	if (n === 1 || n === 2) return 1;
        var n1 = 1
        var n2 = 1
        var result = 0
        for(let i = 3; i <= n; i++) {
          result = n1 + n2
          n1 = n2
          n2 = result
        }
        return result
      }
      consonle.log(foo(10))
      
    • //递归实现斐波那契数列 输入位置显示对应的数列
      function foo(n) {
        if(n === 1 || n === 2) return 1
        return foo(n-1) + foo(n-2)
      }
      console.log(foo(4))
      

局部变量和外部变量

  • JavaScript(ES5之前)中没有块级作用域的概念,但是函数可以定义自己的作用域
    • 作用域 表示一些标识符的作用有效范围(所以也有被翻译为有效范围的);
    • 函数的作用域表示在函数内部定义的变量只有在函数内部可以被访问到
  • 外部变量和局部变量的概念
    • 定义在函数内部的变量,被称之为局部变量
    • 定义在函数外部的变量,被称之为外部变量
  • 什么是全局变量
    • 函数之外声明的变量(在script中声明的),称之为全局变量
    • 全局变量在任何函数中都是可见的
    • 通过var声明的全局变量会在window对象上添加一个属性(了解)
  • 在函数中,访问变量的顺序
    • 优先访问自己函数中的变量,没有找到时,在外部中访问

函数表达式

  • 在JavaScript中,函数并不是一种神奇的语法结构,而是一种特殊的值

    • 前面定义函数的方式,我们称之为函数的声明

    • //函数的声明 定义函数
      function 函数名() {
        //函数内部代码块
      }
      
  • 还有另外一种定义函数的写法是函数表达式

    • var 函数名 = function() {
        //函数内部代码块
      }
      
  • 注意,function 关键字后面没有函数名

    • 函数表达式中 一般省略function后面的函数名
  • 无论函数是如何创建的,函数都是一个值(这个值的类型是一个对象,对象的概念后面会讲到)

  • 在JavaScript开发中,我们可以将函数作为头等公民

  • 函数声明函数表达式的区别

    • 首先,语法不同
      • 函数声明:在主代码流中声明为单独的语句的函数。
      • 函数表达式:在一个表达式中或另一个语法结构中创建的函数
    • 其次,JavaScript创建函数的时机是不同的
      • 函数表达式是在代码执行到达时被创建,并且仅从那一刻起可用
      • 函数声明被定义之前,它就可以被调用
        • 这是内部算法的原故
        • JavaScript 准备 运行脚本时,首先会在脚本中寻找全局函数声明,并创建这些函数
    • 开发中如何选择呢?
      • 当我们需要声明一个函数时,首先考虑函数声明语法
      • 它能够为组织代码提供更多的灵活性,因为我们可以在声明这些函数之前调用这些函数

JavaScript头等函数

  • 头等函数是指在程序设计语言中,函数被当作头等公民

  • 这意味着,函数可以作为别的函数的参数、函数的返回值,赋值给变量或存储在数据结构中

    • // 1.函数可以被赋值给变量(函数表达式写法)
      var foo1 = function() {
      	console.log("foo1函数被执行~")
      }
      
    • // 2.让函数在变量之间来回传递
      var foo1 = function() {
      	console.log("foo1函数被执行~")
      }
      var foo2 = foo1
      foo2()
      
    • // 3.函数可以另外一个函数的参数
      var foo1 = function() {
      	console.log("foo1函数被执行~")
      }
      function bar(fn) {
      	console.log("fn:", fn)
        //作为参数传入进来的函数也可以调用
      	fn()
      }
      bar(foo1)
      
    • // 4.函数作为另外一个函数的返回值
      function sayHello() {
      	function hi() {
      		console.log("hi kobe")
      	}
      	return hi
      }
      var fn = sayHello()
      fn()
      
    • // 5.1将函数存储在另外一个数据结构中(函数放在对象中)
      var obj = {
      	name: "why",
      	eating: function() {
      		console.log("eating")
      	}
      }
      obj.eating()
      
    • // 5.1将函数存储在另外一个数据结构中(函数放在数组中)
      function bar1() {
      	console.log("bar1函数被执行~")
      }
      function bar2() {
      	console.log("bar2函数被执行~")
      }
      function bar3() {
      	console.log("bar3函数被执行~")
      }
      var fns = [bar1, bar2, bar3]
      
  • 有人主张也应包括支持匿名函数

  • 通常我们对作为头等公民的编程方式,称之为函数式编程

    • JavaScript就是符合函数式编程的语言,这个也是JavaScript的一大特点

回调函数

  • 既然函数可以作为一个值相互赋值,那么也可以传递给另外一个函数

    • function foo(fn) {
        //通过fn去调用bar函数的过程, 称之为回调
        fn()
      }
      function bar() {
        console.log("bar函数被调用了~")
      }
      foo(bar)
      
  • foo这种函数我们也可以称之为高阶函数

  • 高阶函数必须至少满足两个条件之一

    • 接受一个或多个函数作为输入;
    • 输出一个函数
  • 匿名函数的理解

    • 如果在传入一个函数时,我们没有指定这个函数的名称或者通过函数表达式指定函数对应的变量,那么这个函数称之为匿名
      函数

立即执行函数

  • 什么是立即执行函数?

    • 专业名字:Immediately-Invoked Function Expression(IIFE 立即调用函数表达式)

    • 表达的含义是一个函数定义完后被立即执行

      • 第一部分是定义了一个匿名函数,这个函数有自己独立的作用域

      • 第二部分是后面的(),表示这个函数被执行了

      • (function() {
          console.log("立即执行函数被调用了")
        })()
        
  • 立即执行函数的作用

    • 在立即执行函数中定义的变量有自己的作用域
    • 创建一个独立的执行上下文环境,可以避免外界访问或修改内部的变量,也避免了对内部变量的修改
    • 防止全局变量命名冲突问题

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/120157.html

(0)
seven_的头像seven_bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!