2025年3月17日 星期一 甲辰(龙)年 月十六 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > JavaScript

掌握JavaScript函数,让你的代码更加优雅

时间:02-23来源:作者:点击数:9

目录

函数的概述

函数的声明

函数的调用

函数的参数

函数的返回值

函数作用域

闭包

回调函数

匿名函数

函数作为参数

案例

使用函数求三个数中的最大数

编程求x的阶乘和y的阶乘的和,要求设计一个fac(n)函数求正整数n的阶乘

利用函数实现面积计算器(计算长方形、三角形、圆形的面积)。Math.PI

计算s=2^2!+3^2!

递归函数

案例

1 + 2 + 3 + …… + 100的和

斐波那契数列

输出10个Hello world

作用域及作用域链详解

函数的概述

  1. 什么是函数?

将一个(反复)使用的功能,封装成一个独立的模块,这个模块叫做函数。

  1. 好处

使程序可控 一次封装,无限次使用(增加代码的复用度)

  1. 函数的类型

Function

  1. 函数的分类

内置函数(库函数、系统函数) 自定义函数

函数的声明

  1. 语句定义法(声明式函数): 可以任意位置调用!
  • function 函数名([参数]){
  •    //功能
  • }
  1. 表达式定义法(赋值式函数):只能先声明,后使用!
  • var 变量名 = function([参数]){
  •    //功能
  • }
  • <script>
  • //声明式函数
  • function fn1(){
  • // 输出1~100中的所有素数(素数:只能被1和它本身整除的数)
  • // 1~100 i = 1;i < 101;i ++
  • // j = 2;j <= 本身; j ++
  • var str = ''; //放置所有素数的变量
  • for(var i = 1;i < 101;i ++){
  • for(var j = 2;j <= i;j ++){
  • if(i % j === 0){
  • break;
  • }
  • }
  • if(i === j){
  • str += i + ' ';
  • }
  • }
  • document.write(str);
  • }
  • fn1();
  • document.write('<br>');
  • fn1();
  • document.write('<br>');
  • fn1();
  • </script>

函数的调用

  1. 一般调用 :函数名([参数])

函数的参数

  1. 形式参数(形参) :声明函数时使用的参数
  2. 实际参数(实参) :调用函数时使用的参数
  • <script>
  • //声明函数
  • function fn(m,n){ //形参(形式参数):用于接收实参的值,必须是变量
  • // 输出m行n列的8
  • //m 行: 从第一行开始,最m行结束,步长
  • var str = '';
  • for(var row = 1;row <= m;row ++){
  • //n 列: 从第一列开始,最n列结束,步长
  • for(var col = 1;col <= n;col ++){
  • str += 8;
  • }
  • str += '\n';
  • }
  • console.log(str);
  • console.log(m,n);
  • }
  • // m = 8
  • var a = parseInt(prompt('请输入行数:'));
  • var b = parseInt(prompt('请输入列数:'));
  • fn(a,b); //实参(实际参数):给形参传递的数据,可以是常量 ,变量,表达式
  • </script>

如果实参的数量少于形参的数量时,多余的形参值为undefined 如果实参的数量多于形参的数量时,多余的实参忽略。

函数的返回值

  1. return
  • 将函数中处理后的结果返回到调用该函数的地方。
  • 退出函数
    • 比如 1 + 2 是一个表达式,那么 这个表达式的结果就是 3
  • console.log(1 + 2) // 3
  • function fn() {
  •  // 执行代码
  • }
  • // fn() 也是一个表达式,这个表达式就没有结果出现
  • console.log(fn()) // undefined
  • <script>
  • //返回值:将函数中处理的功能后,得到的结果返回到调用这个函数的地方。
  • function fn(){
  • // 输出一元钱的兑换方案(1角2角5角)
  • 1角:var one = 0;one < 11;one ++
  • 2角:var two = 0;two < 6;two ++
  • 5角:var five = 0;five < 3;five ++
  • if(1 * one + 2 * two + 5 * five === 10){
  • }
  • var str = '';
  • for(var one = 0;one < 11;one ++){
  • for(var two = 0;two < 6;two ++){
  • for(var five = 0;five < 3;five ++){
  • if(1 * one + 2 * two + 5 * five === 10){
  • str += one + ' 张壹角 ' + two + ' 张贰角 ' + five + ' 张伍角\n';
  • }
  • }
  • }
  • }
  • console.log(str);
  • return str; //将处理后的结果返回到调用这个函数的地方。
  • 退出函数了
  • alert('瞧瞧');
  • }
  • var result = fn(); //调用fn()的函数,将返回的结果str赋值给result变量
  • console.log(result);
  • console.log(fn());
  • fn();
  • console.log(fn());
  • </script>

函数作用域

JavaScript中有全局作用域和函数作用域两种作用域,函数作用域只在函数内部有效。在函数内定义的变量和函数只能在该函数内部访问,不能在函数外部访问。以下是函数作用域的示例:

  • function greet(name) {
  • const message = 'Hello, ' + name + '!';
  • console.log(message);
  • }
  • greet('Alice'); // 输出 Hello, Alice!
  • console.log(message); // 抛出错误:message未定义

闭包

闭包是指在一个函数中定义了另一个函数,并且内部函数可以访问外部函数的变量。在JavaScript中,函数可以嵌套定义,内部函数可以访问外部函数的变量,从而形成闭包。以下是闭包的示例:

  • function add(a) {
  • return function(b) {
  • return a + b;
  • }
  • }
  • const add2 = add(2);
  • console.log(add2(3)); // 输出 5

在上面的示例中,add() 函数返回一个匿名函数,这个匿名函数可以访问 add() 函数的参数 a。定义 add2 变量时,将 add(2) 赋值给它,此时 add2 变量就成为了一个新的函数,这个函数可以接收一个参数并返回参数与 a 的和。

回调函数

回调函数是指将函数作为参数传递给另一个函数,并在另一个函数中调用它。在JavaScript中,回调函数常用于异步编程中,在异步操作完成后执行回调函数。以下是回调函数的示例:

  • function add(a, b, callback) {
  • const result = a + b;
  • setTimeout(function() {
  • callback(result);
  • }, 1000);
  • }
  • add(2, 3, function(result) {
  • console.log(result); // 输出 5
  • });

匿名函数

除了通过function关键字定义函数外,还可以使用匿名函数,例如:

  • var add = function(a, b) {
  • return a + b;
  • };
  • var result = add(3, 4); // 结果为7

函数作为参数

在JavaScript中,函数可以作为参数传递给其他函数,例如:

  • function operate(a, b, operation) {
  • return operation(a, b);
  • }
  • var sum = operate(5, 3, function(x, y) { return x + y; }); // 结果为8
案例
  • 使用函数求三个数中的最大数
  • <script>
  • //使用函数求三个数中的最大数
  • 比较 - 选择语句
  • 1. 先求出前两个数中的最大值 一个条件,两个结果(双分支语句)
  • 2. 再拿前两个数中的最大值与剩下的下数进行比较,一个条件,一个结果(单分支)
  • //求三个数中最大值的函数
  • function fnMax(a,b,c){
  • //求最大值
  • var max = a > b ? a : b;
  • //与剩下的一个数进行比较
  • if(c > max){
  • max = c;
  • }
  • return max;
  • }
  • // alert(fnMax(4,2,5));
  • 编写函数iseven,其功能为判断一个整数是否为偶数,若是偶数,返回1,否则返回0,在程序中调用此函数,对输入的一个整数进行判断,若是偶数,输出even,否则输出odd
  • //封装一个判断奇偶的函数,将结果返回
  • function iseven(n){
  • return n % 2 ? 0 : 1;
  • }
  • // 输入的一个整数
  • var i = parseInt(prompt('请输入一个整数:'));
  • //声明一个变量,接收函数的返回值
  • var result = iseven(i);
  • //根据返回值,判断输出even还是odd
  • alert(result === 1 ? 'even' : 'odd');
  • </script>
  • 编程求x的阶乘和y的阶乘的和,要求设计一个fac(n)函数求正整数n的阶乘
  • <script>
  • 编程求x的阶乘和y的阶乘的和,要求设计一个fac(n)函数求正整数n的阶乘
  • x的阶乘
  • y的阶乘
  • //封装一个求正整数n的阶乘
  • function fac(n){
  • for(var i = 1,result = 1;i <= n;i ++){
  • result *= i;
  • }
  • return result;
  • }
  • //准备两个变量,接收两个整数
  • var x = parseInt(prompt('请输入一个整数:'));
  • var y = parseInt(prompt('请输入一个整数:'));
  • //求和
  • var sum = fac(x) + fac(y);
  • alert(sum);
  • </script>
  • 利用函数实现面积计算器(计算长方形、三角形、圆形的面积)。Math.PI
  • <script>
  • 利用函数实现面积计算器(计算长方形、三角形、圆形的面积)。Math.PI
  • 1. 长方形: 长 * 宽
  • 2. 三角形:底 * 高 / 2
  • 3. 圆形: Math.PI * r * r
  • //封装一个长方形面积的函数
  • function rectangle(long,width){
  • return long * width;
  • }
  • //封装一个三角形面积的函数
  • function triangle(bottom,height){
  • return (bottom * height / 2).toFixed(2);
  • }
  • //封装一个圆形面积的函数
  • function circle(r){
  • return (Math.PI * r * r).toFixed(2);
  • }
  • //封装一个计算器的函数
  • function calculator(){
  • //设计一个无限循环
  • while(1){
  • //提示用户输入功能
  • var n = parseInt(prompt('0: 退出 1: 长方形 2: 三角形 3: 圆形\n请选择:'));
  • //判断
  • switch(n){
  • case 1 :
  • //输入长
  • var long = parseInt(prompt('请输入长方形的长:'));
  • //输入宽
  • var width = parseInt(prompt('请输入长方形的宽:'));
  • alert('长方形的面积是:' + rectangle(long,width));
  • break;
  • case 2 :
  • //输入底
  • var bottom = parseInt(prompt('请输入三角形的底:'));
  • var height = parseInt(prompt('请输入三角形的高:'));
  • alert('三角形的面积是:' + triangle(bottom,height));
  • break;
  • case 3 :
  • //输入半径
  • var r = parseInt(prompt('请输入圆形的半径:'));
  • alert('圆形的面积是:' + circle(r));
  • break;
  • case 0 : return; //退出函数
  • default : alert('其它图形的面积尚未开放,敬请期待!');
  • }
  • }
  • }
  • calculator();
  • </script>
  • 计算s=2^2!+3^2!
  • <script>
  • 计算s=2^2!+3^2!
  • 2^22的平方 2 * 2
  • 阶乘
  • //1. 求平方函数
  • function square(n){
  • return n * n;
  • }
  • //2. 阶乘
  • function fac(n){
  • for(var i = 1,result = 1;i <= n;i ++){
  • result *= i;
  • }
  • return result;
  • }
  • //3. 和
  • function sum(){
  • return fac(square(2)) + fac(square(3));
  • }
  • alert(sum());
  • </script>

递归函数

自己调用自己的过程。

  1. 本质:循环
  2. 三要素:从哪里开始,到哪里结束、步长

建议在循环嵌套不确定层数时,使用递归函数。

  • // 下面这个代码就是一个最简单的递归函数
  • // 在函数内部调用了自己,函数一执行,就调用自己一次,在调用再执行,循环往复,没有止尽
  • function fn() {
  •  fn()
  • }
  • fn()
案例
  • 1 + 2 + 3 + …… + 100的和
  • <script>
  • //递归:实现循环 (三要素)
  • //求 1 + 2 + 3 + …… + n 的和
  • function fnSum(n){ //从哪里开始 5 4 3 2 1
  • //到哪里结束,退出循环的条件
  • if( n === 1){
  • return 1;
  • }else{
  • return n + fnSum(n - 1); //步长
  • // 5 + 4 + 3 + 2 + 1
  • }
  • }
  • console.log(fnSum(5));
  • // 求 n!
  • function fnFac(n){
  • if(n === 1){
  • return 1;
  • }else {
  • return n * fnFac(n - 1);
  • }
  • }
  • console.log(fnFac(5));
  • </script>
  • 斐波那契数列
  • <script>
  • //斐波那契数列: 下一个数是前两个数的和
  • // 1 1 2 3 5 8 13 21 34 55
  • function fib(n){ //循环初值,代表的是第几个斐波那契数字
  • //循环条件(退出条件)
  • if(n == 1 || n == 2){
  • return 1;
  • }else{
  • return fib(n - 1) + fib(n - 2);
  • }
  • }
  • // alert(fib(10));
  • for(var i = 1;i < 21;i ++){
  • console.log(fib(i));
  • }
  • </script>
  • 输出10个Hello world
  • <script>
  • //输出10个Hello world
  • function print(n){
  • if(n === 0){
  • return;
  • }else{
  • console.log('helloworld');
  • print(n - 1);
  • }
  • }
  • print(5);
  • </script>

作用域及作用域链详解

  • <script>
  • //1. 作用域:JS代码作用的范围
  • //2. 一旦进入作用域,浏览器就会启动JS解析器
  • 一、寻找东西? (var function 形参)
  • a = 1
  • fn = function fn(){alert(2)}
  • //1. 当找到var 或者 形参 时,取后面的名字存储在内存中,并给它初始化一个值undefined
  • //2. 当找到function时,取函数名存储在内存中,并将整个函数块赋值给这个函数名.
  • 二、逐行解读代码 (遇到函数声明,则直接跳过)
  • 1. 执行表达式
  • 2. 函数调用
  • alert(a); //undefined
  • var a = 1;
  • alert(a); //1
  • function fn(){
  • alert(2);
  • }
  • alert(a); //1
  • </script>
  • <script>
  • //1. 作用域:JS代码作用的范围
  • //2. 一旦进入作用域,浏览器就会启动JS解析器
  • 一、预解析(寻找东西?) (var function 形参)
  • a = 3
  • //1. 当找到var 或者 形参 时,取后面的名字存储在内存中,并给它初始化一个值undefined
  • //2. 当找到function时,取函数名存储在内存中,并将整个函数块赋值给这个函数名.
  • //3. 当变量名与函数名相同时,丢变量、保函数
  • 二、逐行解读代码 (遇到函数声明,则直接跳过)
  • 1. 执行表达式
  • 2. 函数调用
  • alert(a); //function a(){alert(4)}
  • var a = 1;
  • alert(a); //1
  • function a(){
  • alert(2);
  • }
  • alert(a); //1
  • var a = 3;
  • alert(a); //3
  • function a(){
  • alert(4);
  • }
  • alert(a); //3
  • </script>
  • <script>
  • //1. 作用域:JS代码作用的范围
  • //2. 一旦进入作用域,浏览器就会启动JS解析器
  • 一、预解析(寻找东西?) (var function 形参)
  • fn = function fn(){alert(2)}
  • a = 1
  • //1. 当找到var 或者 形参 时,取后面的名字存储在内存中,并给它初始化一个值undefined
  • //2. 当找到function时,取函数名存储在内存中,并将整个函数块赋值给这个函数名.
  • //3. 当变量名与函数名相同时,丢变量、保函数
  • //4. 当有多个script标签时,从上到下依次解决每一个script标签,所以建议大家 《将所有声明的语句放到第一个script标签中》
  • 二、逐行解读代码 (遇到函数声明,则直接跳过)
  • 1. 执行表达式
  • 2. 函数调用
  • alert(a); //报错
  • function fn(){
  • alert(2);
  • }
  • </script>
  • <script>
  • var a = 1;
  • fn(); //2
  • </script>
  • <script>
  • //1. 作用域:JS代码作用的范围
  • //2. 一旦进入作用域,浏览器就会启动JS解析器(一、预 解析 二、逐行解读代码)
  • //3. var 声明在script作用域的变量,称为全局变量,作用范围是整个页面,生存周期在页面开始运行时开启空间,到页面退出时释放内存空间。同时也是window对象的属性。如果var声明的变量或形参在函数中时,称为局部变量,作用范围仅限于当前函数中,生存周期在函数调用时开启空间,到函数调用结束后,释放内存空间。
  • //4. 作用域链:从一个作用域中未寻找到内容,会向父级作用域中查找,这个向上查找的过程,称为作用域链。
  • 一、预解析(寻找东西?) (var function 形参)
  • a = 2
  • fn = function(){}
  • //1. 当找到var 或者 形参 时,取后面的名字存储在内存中,并给它初始化一个值undefined
  • //2. 当找到function时,取函数名存储在内存中,并将整个函数块赋值给这个函数名.
  • //3. 当变量名与函数名相同时,丢变量、保函数
  • //4. 当有多个script标签时,从上到下依次解决每一个script标签,所以建议大家 《将所有声明的语句放到第一个script标签中》
  • 二、逐行解读代码 (遇到函数声明,则直接跳过)
  • 1. 执行表达式
  • 2. 函数调用 (函数也是一个作用域)
  • 一、预解析
  • 二、逐行解读代码
  • 1. 执行表达式
  • 2. 函数调用
  • alert(a); //undefined
  • var a = 1;
  • alert(a); //1
  • function fn(){
  • alert(a); //1
  • a = 2;
  • alert(a); //2
  • }
  • fn();
  • alert(a); //2
  • </script>
  • <script>
  • //1. 作用域:JS代码作用的范围
  • //2. 一旦进入作用域,浏览器就会启动JS解析器(一、预 解析 二、逐行解读代码)
  • //3. var 声明在script作用域的变量,称为全局变量,作用范围是整个页面,生存周期在页面开始运行时开启空间,到页面退出时释放内存空间。同时也是window对象的属性。如果var声明的变量或形参在函数中时,称为局部变量,作用范围仅限于当前函数中,生存周期在函数调用时开启空间,到函数调用结束后,释放内存空间。
  • //4. 作用域链:从一个作用域中未寻找到内容,会向父级作用域中查找,这个向上查找的过程,称为作用域链。
  • 一、预解析(寻找东西?) (var function 形参)
  • a = 1
  • fn = function(){}
  • //1. 当找到var 或者 形参 时,取后面的名字存储在内存中,并给它初始化一个值undefined
  • //2. 当找到function时,取函数名存储在内存中,并将整个函数块赋值给这个函数名.
  • //3. 当变量名与函数名相同时,丢变量、保函数
  • //4. 当有多个script标签时,从上到下依次解决每一个script标签,所以建议大家 《将所有声明的语句放到第一个script标签中》
  • 二、逐行解读代码 (遇到函数声明,则直接跳过)
  • 1. 执行表达式
  • 2. 函数调用 (函数也是一个作用域)
  • 一、预解析
  • a = 2
  • 二、逐行解读代码
  • 1. 执行表达式
  • 2. 函数调用
  • alert(a); //undefined
  • var a = 1;
  • alert(a); //1
  • function fn(){
  • alert(a); //undefined
  • var a = 2;
  • alert(a); //2
  • }
  • fn();
  • alert(a); //1
  • </script>
  • <script>
  • //1. 作用域:JS代码作用的范围
  • //2. 一旦进入作用域,浏览器就会启动JS解析器(一、预 解析 二、逐行解读代码)
  • //3. var 声明在script作用域的变量,称为全局变量,作用范围是整个页面,生存周期在页面开始运行时开启空间,到页面退出时释放内存空间。同时也是window对象的属性。如果var声明的变量或形参在函数中时,称为局部变量,作用范围仅限于当前函数中,生存周期在函数调用时开启空间,到函数调用结束后,释放内存空间。
  • //4. 作用域链:从一个作用域中未寻找到内容,会向父级作用域中查找,这个向上查找的过程,称为作用域链。
  • 一、预解析(寻找东西?) (var function 形参)
  • a = 1
  • fn = function(){}
  • //1. 当找到var 或者 形参 时,取后面的名字存储在内存中,并给它初始化一个值undefined
  • //2. 当找到function时,取函数名存储在内存中,并将整个函数块赋值给这个函数名.
  • //3. 当变量名与函数名相同时,丢变量、保函数
  • //4. 当有多个script标签时,从上到下依次解决每一个script标签,所以建议大家 《将所有声明的语句放到第一个script标签中》
  • 二、逐行解读代码 (遇到函数声明,则直接跳过)
  • 1. 执行表达式
  • 2. 函数调用 (函数也是一个作用域)
  • 一、预解析
  • a = 2
  • 二、逐行解读代码
  • 1. 执行表达式
  • 2. 函数调用
  • var a = 1;
  • alert(a); //1
  • function fn(a){ //形参
  • alert(a); //undefined
  • a = 2;
  • alert(a); //2
  • }
  • fn();
  • alert(a); //1
  • </script>
  • <script>
  • //1. 作用域:JS代码作用的范围
  • //2. 一旦进入作用域,浏览器就会启动JS解析器(一、预 解析 二、逐行解读代码)
  • //3. var 声明在script作用域的变量,称为全局变量,作用范围是整个页面,生存周期在页面开始运行时开启空间,到页面退出时释放内存空间。同时也是window对象的属性。如果var声明的变量或形参在函数中时,称为局部变量,作用范围仅限于当前函数中,生存周期在函数调用时开启空间,到函数调用结束后,释放内存空间。
  • //4. 作用域链:从一个作用域中未寻找到内容,会向父级作用域中查找,这个向上查找的过程,称为作用域链。
  • 一、预解析(寻找东西?) (var function 形参)
  • a = 1
  • fn = function(){}
  • //1. 当找到var 或者 形参 时,取后面的名字存储在内存中,并给它初始化一个值undefined
  • //2. 当找到function时,取函数名存储在内存中,并将整个函数块赋值给这个函数名.
  • //3. 当变量名与函数名相同时,丢变量、保函数
  • //4. 当有多个script标签时,从上到下依次解决每一个script标签,所以建议大家 《将所有声明的语句放到第一个script标签中》
  • 二、逐行解读代码 (遇到函数声明,则直接跳过)
  • 1. 执行表达式
  • 2. 函数调用 (函数也是一个作用域)
  • 一、预解析
  • a = 2
  • 二、逐行解读代码
  • 1. 执行表达式
  • 2. 函数调用
  • var a = 1;
  • alert(a); //1
  • function fn(a){ //形参 a = 1
  • alert(a); //1
  • a = 2;
  • alert(a); //2
  • }
  • fn(a); //实参
  • alert(a); //1
  • </script>
  • <script>
  • //1. 作用域:JS代码作用的范围
  • //2. 一旦进入作用域,浏览器就会启动JS解析器(一、预 解析 二、逐行解读代码)
  • //3. var 声明在script作用域的变量,称为全局变量,作用范围是整个页面,生存周期在页面开始运行时开启空间,到页面退出时释放内存空间。同时也是window对象的属性。如果var声明的变量或形参在函数中时,称为局部变量,作用范围仅限于当前函数中,生存周期在函数调用时开启空间,到函数调用结束后,释放内存空间。
  • //4. 作用域链:从一个作用域中未寻找到内容,会向父级作用域中查找,这个向上查找的过程,称为作用域链。
  • 一、预解析(寻找东西?) (var function 形参)
  • a = 2
  • fn = function(){}
  • //1. 当找到var 或者 形参 时,取后面的名字存储在内存中,并给它初始化一个值undefined
  • //2. 当找到function时,取函数名存储在内存中,并将整个函数块赋值给这个函数名.
  • //3. 当变量名与函数名相同时,丢变量、保函数
  • //4. 当有多个script标签时,从上到下依次解决每一个script标签,所以建议大家 《将所有声明的语句放到第一个script标签中》
  • //5. 如果在所有的作用域中都没有找到这个变量,则会在全局作用域中因为赋值号的原因,自动生成这个变量。
  • 二、逐行解读代码 (遇到函数声明,则直接跳过)
  • 1. 执行表达式
  • 2. 函数调用 (函数也是一个作用域)
  • 一、预解析
  • 二、逐行解读代码
  • 1. 执行表达式
  • 2. 函数调用
  • function fn(){
  • a = 2;
  • alert(a); //2
  • }
  • fn();
  • alert(a); //2
  • </script>
方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门
本栏推荐