函数基础,定义与调用。作用域,闭包函数
一、函数的定义与调用
函数是一段可重复使用的代码块,用于执行特定任务或计算等功能。它可以接受输入参数(形参),并根据参数执行操作后返回结果。
函数的定义
例如在 JavaScript 中可以这样定义函数:
function fun() { return "Hello,world"; }
函数的调用
通过函数名加小括号的方式调用函数,如document.write(fun());。一个函数可以有多个return语句,但调用时只有第一个return语句被执行,其后面表达式的值作为返回值,后面的代码被忽略。函数返回值无类型限制。
函数的形参和实参
形参
是声明函数时写在函数名后的小括号内的参数,用变量名接收,如
function add(x, y)中的x和y。
实参
是调用函数时写在小括号内的参数,如add(1, 2)中的1和2。形参和实参一一对应,如果形参没有实参对应,形参拿到的是undefined。
this 关键字
this 是一个关键字,在函数执行过程中能访问运行环境,它是一个对象,其值根据函数的调用方式和上下文而变化,与函数的执行环节有关,与声明无关。它指向当前函数的运行环境,能在函数内部访问和操作当前对象的属性和方法。
函数的不同调用方式
作为方法被调用
当函数被赋值给一个对象的属性,并通过对象属性引用的方式调用函数时,函数作为对象的方法被调用。例如:
var person = {Name: "liux",Name2: "Dog",fullName: function() {return this.Name + " " + this.Name2;}};console.log(person.fullName());
使用构造函数调用函数
使用关键字new调用函数时,会创建一个新对象并作为this参数传递给构造函数,构造函数进行初始化设置后将新对象作为返回值。例如:
function a2(name) {this.name = name;this.greet = function() {console.log("你好,我是" + this.name);};}var a3 = new a2("lx");a3.greet();
作为函数方法调用函数
不同类型函数调用的主要区别在于最终作为函数上下文(this)传递给执行函数的对象不同。可以使用call()和apply()方法显式指定函数调用时的上下文。call()接收参数列表,apply()接收数组作为参数。例如:
function add(a, b) {return a + b;}// 使用call()result1 = add.call(result1, 2, 3);// 使用apply()Array = [2, 3];result2 = add.apply(result2, Array);
二、函数参数设置
有参函数和无参函数
无参函数
定义函数时不设置参数,如
function A() { console.log("Hello World!"); }。
有参函数
定义函数时设置了参数,如
function B(name) { console.log("Hello " + name + "!"); }。
函数参数的其他特性
含有默认值的参数
在设置函数形参时可指定默认值,当调用者未传递该参数时,函数使用默认值操作。例如
function C(name = "World") { console.log("Hello " + name + "!"); }。
剩余参数
函数定义时可利用 “… 变量名” 的方式动态接收不确定数量的实参,如function D(...args) { console.log(args); }。
函数内外变量的作用域
全局变量
在函数外定义的变量是全局变量,可在函数内部和外部访问,如
var globalVar = 'I am a global variable';。
局部变量
在函数内部使用var关键字定义的变量是局部变量,只能在该函数内部访问。未使用var定义的变量在函数内部也是局部变量。函数的参数也是局部变量。例如:
function localScope() {var localVar = 'I am a local variable';console.log(localVar);}localScope();
三、进阶函数
函数表达式
函数达式是将声明的函数赋值给一个变量,通过 “变量名 ()” 的方式调用函数,定义必须在调用前。与函数定义方式不同,函数表达式的定义顺序有要求且函数名可省略。例如
var fn = function sum(num1, num2) { return num1 + num2; }; fn(2, 3);。
匿名函数
为什么要用匿名函数
团队合作时可避免函数名冲突。
匿名函数的实现方式
包括函数表达式中省略函数名,如var fn = function (num1, num2) { return num1 + num2; };;匿名函数自调用,如(function (num1, num2) { console.log(num1 + num2); })(2, 3);;处理事件,如document.body.onclick = function () { alert('Hi, everybody!'); }。
箭头函数
特点
箭头函数可视为一种匿名函数形式,用于简化函数定义语法,没有传统函数名,通过箭头(=>)定义函数体。通常用于不需要显式函数名的场景,如作为回调函数传递给其他函数。
语法
箭头函数的小括号中可传入参数,如var fn = (num1, num2) => { return num1 + num2; };。当函数体只有一句代码且执行结果是返回值时,可省略大括号和return关键字;当参数只有 1 个时,可省略参数外部小括号。
回调函数
定义
一个函数 A 作为参数传递给一个函数 B,然后在 B 的函数体内调用函数 A,称函数 A 为回调函数。
同步回调
同步回调是阻塞的,回调函数在调用它的函数完成任务后立即执行,程序执行顺序是线性的。例如:f
unction A1(a, b, callback) {var result = a + b;if (typeof callback === 'function') {callback(result);}}function A2(result) {console.log('计算结果是: ' + result);}A1(3, 4, A2);
异步回调
异步回调是非阻塞的,回调函数在调用它的函数完成任务之后某个时间点执行。例如:
function add(a, b, callback) {setTimeout(function() {callback(a + b);}, 1000);}function aResult(result) {console.log("结果是:" + result);}add(2, 3, aResult);
异步回调函数与异步函数
异步回调函数
使用回调函数处理异步操作,适合简单情况,但代码可能较复杂。例如模拟点奶茶,服务员准备奶茶时顾客可做其他事,准备好后调用回调函数通知顾客。
异步函数
使用async和await关键字简化异步操作执行,让异步代码更像同步代码,提高可读性和可维护性。例如使用异步函数点奶茶,顾客点餐后可先去做别的事,等餐时通过await暂停代码执行,拿到奶茶后继续执行。
四、函数作用域相关
作用域的概念
作用域是可访问变量的集合,是根据名称查找变量的一套规则。JavaScript 采用词法作用域(静态作用域),包括全局作用域和函数作用域。
全局作用域
在最外层函数和最外层函数外面定义的变量拥有全局作用域,所有脚本和函数均可使用。例如var carName = "Volvo";在任何脚本和函数内均可访问。
局部作用域
变量在函数内声明为局部变量,其生命周期仅限于函数执行期间,外部无法直接访问。只有函数的{}构成作用域,对象的{}以及if() {}都不构成作用域。let和const声明的变量会产生块作用域,var不会。例如:
function myFunction() {var carName = "Volvo";}
词法作用域
词法作用域依据变量在源代码中的位置查找变量,从当前作用域开始向上遍历到包含它的所有外层作用域,直到找到定义。其特点包括静态作用域、封闭作用域和模块化。例如内部函数可访问外部函数中定义的变量。
变量提升
变量提升是指变量声明会被提前到其所在作用域的顶部,但只有变量声明会被提升,而不是变量赋值。例如var关键字定义的变量可以在使用后声明。
块级作用域
块级作用域是在代码块({}包裹部分)内声明的作用域,ES6 引入,通过let和const关键字声明的变量具有块级作用域,只能在声明所在代码块内可见。例如:
if(true){let var5="var5";console.log(var5)}
作用域链
作用域链是由多个嵌套的作用域组成的机制,用于解析标识符(变量和函数),决定了变量和函数的查找顺序。从当前作用域开始查找,找不到则向上一级作用域查找,直到找到或达到全局作用域。例如内部函数可访问自身、外层函数和全局作用域内的变量。
五、闭包函数
闭包的概念
闭包函数是在一个函数内部创建的函数,内部函数可以访问到外部函数的变量和参数,即使外部函数执行完毕,这些变量和参数仍然能够被内部函数访问。
闭包的特点
- 让外部访问函数内部变量成为可能。
- 局部变量会常驻在内存中。
- 可以避免使用全局变量,防止全局变量污染。
- 会造成内存泄漏。
闭包的创建
闭包通常是在另一个函数内部定义一个函数,内部函数作为原函数的返回值返回。例如:
function 外部函数() {var 局部变量 = "我是一个局部变量";function 内部函数() {console.log(局部变量);}return 内部函数;}var 闭包 = 外部函数();闭包();
闭包的应用
- 创建私有变量和方法,用于模块化编程。
- 在事件处理器和回调函数中保持变量的状态,用于异步编程。
- 实现柯里化和函数组合等高级函数编程技巧。
闭包的注意事项
闭包会保留外部函数的变量,可能导致额外的内存消耗和内存泄漏,使用时需注意内存管理和性能问题。
六、递归函数
递归函数是自身调用自身的函数,但要注意一定要有递归结束的条件,并且要改变递归条件的代码。例如求 1 - 100 的累加值的递归函数:
function sum(n) {if(n == 1) {return 1;}return sum(n - 1) + n;}sum(100);

相关文章:
函数基础,定义与调用。作用域,闭包函数
一、函数的定义与调用 函数是一段可重复使用的代码块,用于执行特定任务或计算等功能。它可以接受输入参数(形参),并根据参数执行操作后返回结果。 函数的定义 例如在 JavaScript 中可以这样定义函数: function fun…...
【Linux网络编程】 --- Linux权限理解
Welcome to 9ilks Code World (๑•́ ₃ •̀๑) 个人主页: 9ilk (๑•́ ₃ •̀๑) 文章专栏: Linux网络编程 🏠 shell命令以及运行原理 📌 引入例子理解shell 假设八里村有一个人叫张三,他的父亲是这个村的村长…...
Qt/C++ 调用迅雷开放下载引擎(ThunderOpenSDK)下载数据资源
目录导读 前言ThunderOpenSDK 简介参考 xiaomi_Thunder_Cloud 示例ThunderOpenSDK 下载问题 前言 在对以前老版本的exe执行程序进行研究学习的时候,发现以前的软件是使用的ThunderOpenSDK这个迅雷开放下载引擎进行的项目数据下载,于是在网上搜索一番找到…...
深入详解 Java - Spring MVC
在 Java 企业级开发领域,Spring MVC 是一个极为重要的框架,它为构建强大、灵活且高效的 Web 应用程序提供了坚实的基础。本文将深入详解 Java 之 Spring MVC,带你领略其强大之处。 一、Spring MVC 概述 Spring MVC 是 Spring 框架的一个重要模块,全称为 Spring Web Model-V…...
Spring Boot技术中小企业设备管理系统设计与实践
6系统测试 6.1概念和意义 测试的定义:程序测试是为了发现错误而执行程序的过程。测试(Testing)的任务与目的可以描述为: 目的:发现程序的错误; 任务:通过在计算机上执行程序,暴露程序中潜在的错误。 另一个…...
动态渲染组件
引言 在现代前端开发中,动态渲染组件是一种常见的需求,特别是在构建复杂的应用程序时。动态渲染组件允许我们在运行时根据不同的条件或数据来决定渲染哪个组件,从而提高代码的灵活性和可维护性。本文将详细介绍如何在 Vue.js 中实现动态渲染…...
一个神秘的新图像生成模型red_panda出现 轻松击败Midjourney与OpenAI
一个神秘的新图像生成模型在众包人工分析基准测试中击败了 Midjourney、黑森林实验室和 OpenAI 的模型。这个名为"red_panda"的模型在人工分析的文本到图像排行榜上领先排名第二的黑森林实验室的 Flux1.1 Pro 约 40 个 Elo 分数。 Artificial Analysis 使用 Elo&…...
云计算平台上的DevOps实践
文章目录 什么是DevOps云计算平台上的DevOps优势自动化部署弹性伸缩地理分布 实施DevOps的关键组件版本控制系统持续集成/持续交付工具配置管理工具监控和日志管理 实践案例使用AWS CodePipeline进行持续集成/持续交付利用AWS Auto Scaling实现弹性使用AWS CloudFormation进行基…...
JS新功能之:全新 Set 方法
JavaScript 的内置Set类将新增一些方法,以便执行集合论中常见的操作,包括: Set.prototype.intersection(other):返回两个集合的交集。 Set.prototype.union(other):返回两个集合的并集。 Set.prototype.difference(o…...
Flume的安装配置
一、上传解压 tar -zxvf apache-flume-1.9.0-bin.tar.gz -C /usr/local/soft/#***在环境变量中增加如下命令,可以使用 soft 快速切换到 /usr/local/soft***alias softcd /usr/local/soft/ 二、配置环境变量 soft #重命名 mv apache-flume-1.9.0-bin/ flume-1.9.0…...
3.1.3 虚存页面的映射
3.1.3 虚存页面的映射 文章目录 3.1.3 虚存页面的映射3.1.3 虚存页面的映射MmCreateVirtualMapping()MmCreateVirtualMappingUnsafe()MiFlushTlb()MmDeleteVirtualMapping()MmPageOu…...
【SSM详细教程】-14-SpringAop超详细讲解
精品专题: 01.《C语言从不挂科到高绩点》课程详细笔记 https://blog.csdn.net/yueyehuguang/category_12753294.html?spm1001.2014.3001.5482 02. 《SpringBoot详细教程》课程详细笔记 https://blog.csdn.net/yueyehuguang/category_12789841.html?spm1001.20…...
虚拟机桥接模式连不上,无法进行SSH等远程操作
说明:以下情况在window10上遇到,解决后顺便做了个笔记,以防后续再次用到,也给同道中人提供一个解决方案 一、首先按照以下步骤进行检查 1、是否连接了对应的wifi 2、是否设置了桥接模式 3、上述1、2确认无误的情况下请查看右上…...
jmeter基础01-1_环境准备-windows系统安装jdk
课程大纲 一、步骤解说 step1. jdk官网下载 Java Downloads | Oracle step2. 安装/解压(二选一) 1. 安装包格式(后缀.exe/.msi/.dmg):双击跟随界面向导安装,可以指定安装位置等。 2. 压缩包格式(后缀.z…...
第六天: C语言核心概念与实战技巧全解析
1 主函数(main) 大家好,今天我们来深入探讨一下C语言中非常特殊的一个函数——main函数。虽然大家对它并不陌生,但是它的重要性和特殊性值得我们再次回顾。 main函数的定义 main函数是我们整个C源程序的入口点。计算机在运行程…...
初始JavaEE篇——多线程(5):生产者-消费者模型、阻塞队列
找往期文章包括但不限于本期文章中不懂的知识点: 个人主页:我要学编程程(ಥ_ಥ)-CSDN博客 所属专栏:JavaEE 文章目录 阻塞队列生产者—消费者模型生产者—消费者模型的优势:生产者—消费者模型的劣势: Java标准库中的阻…...
2024年下教师资格证面试报名详细流程❗
⏰ 重要时间节点: (一)下半年笔试成绩查询:11月8日10:00 (二)注册报名:11月8日10:00-11日18:00 (三)网上审核:11月8日10:00-11日18:00 (四&#x…...
软考:常用协议和端口号
常用协议及其对应的端口号如下: TCP/IP协议: TCP(传输控制协议):端口号为6UDP(用户数据报协议):端口号为17 网络应用协议: HTTP(超文本传输协议)…...
Linux更改符号链接
目录 1. 删除旧链接 2. 创建新的符号链接 例如我的电脑上有两个版本的cuda,11.8和12.4 1. 删除旧链接 rm cuda 2. 创建新的符号链接 ln -s /usr/local/cuda-11.8/ /usr/local/cuda...
int main(int argc,char* argv[])详解
#include <stdio.h> //argc 是指命令行输入参数的个数; //argv[]存储了所有的命令行参数, //arg[0]通常指向程序中的可执行文件的文件名。在有些版本的编译器中还包括程序文件所在的路径。 //如:"d:\Production\Software\VC_2005_Test\Win32控制台应用程序\Vc_T…...
MFC内存泄露
1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...
(二)TensorRT-LLM | 模型导出(v0.20.0rc3)
0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述,后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作,其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...
理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端
🌟 什么是 MCP? 模型控制协议 (MCP) 是一种创新的协议,旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议,它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...
为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?
在建筑行业,项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升,传统的管理模式已经难以满足现代工程的需求。过去,许多企业依赖手工记录、口头沟通和分散的信息管理,导致效率低下、成本失控、风险频发。例如&#…...
【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)
骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术,它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton):由层级结构的骨头组成,类似于人体骨骼蒙皮 (Mesh Skinning):将模型网格顶点绑定到骨骼上,使骨骼移动…...
【HTTP三个基础问题】
面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...
[Java恶补day16] 238.除自身以外数组的乘积
给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O(n) 时间复杂度…...
GC1808高性能24位立体声音频ADC芯片解析
1. 芯片概述 GC1808是一款24位立体声音频模数转换器(ADC),支持8kHz~96kHz采样率,集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器,适用于高保真音频采集场景。 2. 核心特性 高精度:24位分辨率,…...
C/C++ 中附加包含目录、附加库目录与附加依赖项详解
在 C/C 编程的编译和链接过程中,附加包含目录、附加库目录和附加依赖项是三个至关重要的设置,它们相互配合,确保程序能够正确引用外部资源并顺利构建。虽然在学习过程中,这些概念容易让人混淆,但深入理解它们的作用和联…...
零知开源——STM32F103RBT6驱动 ICM20948 九轴传感器及 vofa + 上位机可视化教程
STM32F1 本教程使用零知标准板(STM32F103RBT6)通过I2C驱动ICM20948九轴传感器,实现姿态解算,并通过串口将数据实时发送至VOFA上位机进行3D可视化。代码基于开源库修改优化,适合嵌入式及物联网开发者。在基础驱动上新增…...
