【JavaScript】深度理解js的函数(function、Function)

news2024/9/22 5:21:44

简言

学了这么久的JavaScript,函数在JavaScript中最常用之一,如果你不会函数,你就不会JavaScript。
函数就是Function对象,一个函数是可以通过外部代码调用的一个“子程序”,它是头等(first-class)对象,因为它们可以像任何其他对象一样具有属性和方法。瞧瞧它的定义,注定它能做很多事情。
**函数是函数名、参数和函数体组成,然后由function声明。**我们一般说函数是指普通函数,还有另一种函数叫做生成器函数,这个生成器比较比较高级,生成器函数在执行时能暂停,后面又能从暂停处继续执行,这里不展开描述。

函数

在 JavaScript 中,每个函数其实都是一个Function对象。函数默认返回undefined

定义函数

声明一个函数(Function对象)有很多种方式。如果一个函数中没有使用 return 语句,则它默认返回undefined。要想返回一个特定的值,可以使用return 返回。

function声明

由function声明的函数,函数名会提升这个作用域的顶部,即在函数定义前也能使用。

function name([param[, param[, ... param]]]) { statements }
  • name 函数名。
  • param 传递给函数的参数的名称。
  • statements 组成函数体的声明语句。

函数表达式

由函数表达式创建的函数,函数名不会会提升,即必须在创建之后使用。

var myFunction = function name([param[, param[, ... param]]]) { statements }
  • name 函数名,可以省略,省略了后是匿名函数。
  • param 传递给函数的参数的名称。
  • statements 组成函数体的声明语句。

立即调用函数(IIFE)

当函数只使用一次时,通常使用IIFE (Immediately Invokable Function Expressions)。意思是当这个js文件被执行时调用一次。

(function () {
  statements;
})();
  • statements 组成函数体的声明语句。

箭头函数表达式(=>)

箭头函数是函数

var fn = ([param] [, param]) => { statements } param => expression
  • param 参数名称。
    零参数需要用 () 表示。只有一个参数时不需要括号。(例如 foo => 1)
  • statements or expression
    多个声明 statements 需要用大括号括起来,而单个表达式时则不需要。表达式 expression 也是该函数的隐式返回值。

Function构造函数 (不推荐)

函数(Function对象)可以用 new 操作符创建。
把 Function 的构造函数当作函数一样调用 (不使用 new 操作符) 的效果与作为 Function 的构造函数调用一样。

new Function (arg1, arg2, ... argN, functionBody)
  • arg1, arg2, … argN
    函数使用零个或多个名称作为正式的参数名称。每一个必须是一个符合有效的 JavaScript 标识符规则的字符串或用逗号分隔的字符串列表,例如“x”,“theValue”或“a,b”。

  • functionBody
    一个构成的函数定义的,包含 JavaScript 声明语句的字符串。

函数参数

函数参数(形参)一个重要的概念,它是函数体与外面作用域交互的媒介或桥梁。普通的参数由js各种类型定义,除此之外,它还有this、剩余参数和arguments对象。

形参

普通的参数由js各种类型定义,定义的参数可以在函数内使用,想传啥就传啥。
调用传参时,则按你定义参数的顺序传。

function fnParams(
  name,
  age = 18,
  object = {
    label: 'object形参',
  },
  fn = () => {},
  date = new Date(),
  arr = []
) {
  console.log(name, age, object, fn, date, arr)
}
fnParams()

调用时不传参数,参数为undefined,有默认值则值为默认值。
在这里插入图片描述

arguments对象

arguments 是一个对应于传递给函数的参数的类数组对象。
arguments对象是所有(非箭头)函数中都可用的局部变量。你可以使用arguments对象在函数中引用函数的参数。
箭头函数使用arguments在浏览器环境下会报错。

function fnParams(
  name,
  age = 18,
  object = {
    label: 'object形参',
  },
  fn = () => {},
  date = new Date(),
  arr = []
) {
  console.log(name, age, object, fn, date, arr)
  console.log(arguments)
}
fnParams('zsk', () => {})

const fn = (name) => {
  console.log(name, arguments)
}
fn('zsk')

在这里插入图片描述

剩余参数

剩余参数是es6的,剩余参数语法允许我们将一个不定数量的参数表示为一个数组。
如果函数的最后一个命名参数以…为前缀,则它将成为一个由剩余参数组成的真数组,其中从0(包括)到theArgs.length(排除)的元素由传递给函数的实际参数提供。

function(a, b, ...theArgs) {
  // ...
}

如上,theArgs就是剩余参数,它是一个数组,包含那些没有对应形参的实参,默认值[],不能更改默认值。

let fn = function (a, ...args) {
  console.log(a, args)
}
fn(1, 2, 3)

在这里插入图片描述

this

在绝大多数情况下,函数的调用方式决定了 this 的值(运行时绑定)。this 不能在执行期间被赋值,并且在每次函数被调用时 this 的值也可能会不同。可以使用 bind 方法来设置函数的 this 值,而不用考虑函数如何被调用的。箭头函数本身没有this,值为创建时外层上下文对象。

function fn2() {
  console.log('fn2::', this)
  const arrowFn = (a = 1) => {
    console.log('()=>{} ::', this)
  }
  const fn = function (a = 1) {
    console.log('fn::', this)
  }
  arrowFn()
  fn()
  let o = {
    fn: fn,
  }
  o.fn()
}
fn2()

在这里插入图片描述
bind()、call() 和 apply()方法可以改变this值。

a = 1
const obj = {
  a: 2,
}
function fn3() {
  // 'use strict'
  console.log(this.a)
  return this
}
fn3()

fn3.bind(obj)()
fn3()
fn3.bind()()
fn3.call(obj, 1, 2)
fn3()
fn3.call()

fn3.apply(obj, [1, 2])
fn3()
fn3.apply()

在这里插入图片描述

函数体

函数体没啥说的,什么都可以写。自己都可以调用。。。,递归就是这么来的。
如果有return 的话,可以返回函数,例如实现闭包、函数柯里化、高阶函数等。

函数属性

另外,函数本身还有一些属性和方法:

  • name 返回函数定义的名称。
  • length 只读属性,表示函数形参的个数
  • prototype 函数的原型对象
  • toString() 返回函数完整的源代码字符串

结语

有了函数,js就算玩出花来,也可以有条理性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1381389.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于springboot+vue2的灾区物资管理系统(Java毕业设计)

大家好,我是DeBug,很高兴你能来阅读!作为一名热爱编程的程序员,我希望通过这些教学笔记与大家分享我的编程经验和知识。在这里,我将会结合实际项目经验,分享编程技巧、最佳实践以及解决问题的方法。无论你是…

Unity图片导入趣事随笔

像这样的png格式的图片,直接导入unity时unity会把没有像素的部分用黑色填充,并根据填充部分自动生成alpha通道。看起来alpha通道是不能手动覆盖的,即使在ps中手动添加一个alpha通道,并添加覆盖值。 导出后也会发现这没有任何意义&…

整合junit与热部署

整合junit <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><version>2.7.0</version></dependency> 测试类上添加SpringBootTest 如&#xff1a; 注意测试类的…

第11章 GUI Page496~498 步骤三十二:打开画板文件01

tool_4_save_load.hpp添加新内容&#xff1a; 源文件中&#xff0c;新增的四个函数实现为&#xff1a; 为各图元类加上从流中加载图元数据的功能&#xff0c;先是接口声明&#xff1a; 各图元实现接口&#xff1a; 直线&#xff1a; 圆&#xff1a; 十字形&#xff1a; 方框&a…

【PostgreSQL创建索引的锁分析和使用注意】

1.1 创建普通B-tree索引的整体流程 如下是梳理的创建普通B-tree索引的大概流程&#xff0c;可供参考。 1.校验新索引的Catalog元数据|语法解析 ---将创建索引的sql解析成IndexStmt结构&#xff5c;校验B-Tree的handler -----校验内核是否支持该类型的索引,在pg_am中查找&q…

C++STL

STL基本概念 standard template library : 标准模板库STL从广义上可以分为&#xff1a; 容器(container) 算法(algorithm) 迭代器(iterator)。 容器和算法之间通过迭代器进行无缝连接。 STL几乎所有的代码都采用了模板类或者模板函数STL六大组件 STL的容器 STL的容器就是将运…

JAVA实现循环日期加一天

一、业务背景 现在数据库新增字段需要区分平日(0)和假期(1)的数据&#xff0c;之前有一批去年的数据都没有算过&#xff0c;所以得用日期循环来根据实际的时间来修改对应的数值&#xff0c;废话不多说看具体操作方法。 二、操作方法 // 初始日期 String dateString "20…

解密Mybatis-Plus:优雅简化你的数据访问层!

目录 1、引言 2、什么是Mybatis-Plus 3、Mybatis-Plus的特点和优势 4、安装和配置Mybatis-Plus 5、使用Mybatis-Plus进行数据库操作 6、Mybatis-Plus的高级功能 7、Mybatis-Plus的扩展和插件 8、与Spring Boot集成 9、结语 1、引言 Mybatis-Plus是一个强大而优雅的Jav…

idea中使用Lombok 失效,@Slf4j 找不到符号的解决办法

文章目录 一、前言二、问题排查和解决方案三、 其他解决方案3.1 另一种解决方案3.2 参考文章 一、前言 今天在一个多module工程中&#xff0c;新增了一个 springboot&#xff08;版本 2.2.4.RELEASE&#xff09; module&#xff0c;像往常一样&#xff0c;我引入了lombok依赖&…

2D绘图--视口窗口setViewport setWindow

目录 1 setViewport setWindow 2 示例 3 实际应用&#xff08;个人理解&#xff09; 4 总结 1 setViewport setWindow 在Qt中&#xff0c;QPainter的setViewport()方法用于定义绘图区域在窗口坐标系中的可视部分。 QPainter::setWindow() 是 Qt 库中 QPainter 类的一个方法…

【从零开始学习Java重要集合】深入解读ThreadLocal类

目录 前言&#xff1a; ThreadLocal&#xff1a; ThreadLocal的内部结构&#xff1a; ThreadLocal的常用方法&#xff1a; 1.set方法&#xff1a; 2.get方法&#xff1a; 3.setInitialValue方法 remove方法&#xff08;&#xff09;&#xff1a; ThreadLocalMap&…

Kubernetes 集群管理—日志架构

日志架构 应用日志可以让你了解应用内部的运行状况。日志对调试问题和监控集群活动非常有用。 大部分现代化应用都有某种日志记录机制。同样地&#xff0c;容器引擎也被设计成支持日志记录。 针对容器化应用&#xff0c;最简单且最广泛采用的日志记录方式就是写入标准输出和标…

stm32 - 基础架构

stm32 - 基础架构 基础架构外设概念系统结构引脚定义晶振工程 基础架构 外设概念 NVIC &#xff08;内核外设&#xff09; SysTick &#xff08;内核外设&#xff09; 其他是片上外设 系统结构 内核引出三条总线 ICode 指令总线&#xff1a; 连接Flash闪存&#xff08;编写的…

数据结构与算法之美学习笔记:47 | 向量空间:如何实现一个简单的音乐推荐系统?

这里写自定义目录标题 前言算法解析总结引申 前言 本节课程思维导图&#xff1a; 很多人都喜爱听歌&#xff0c;以前我们用 MP3 听歌&#xff0c;现在直接通过音乐 App 在线就能听歌。而且&#xff0c;各种音乐 App 的功能越来越强大&#xff0c;不仅可以自己选歌听&#xff0…

【Docker】Linux中Docker镜像结构及自定义镜像,并且上传仓库可提供使用

目录 一、镜像结构 1. 基本结构 2. 常用命令 二、自定义镜像 1. 基本镜像 2. 进阶镜像 3. 完善镜像 三、镜像上传仓库 每篇一获 一、镜像结构 自定义 Docker 镜像有很多用途&#xff0c;以下是一些主要的应用场景&#xff1a; 一致性环境&#xff1a;通过自定义镜像&a…

PPT文档怎么转换PDF?一个方法教你快速实现

在我们的办公、学习中难免会遇到需要将ppt转pdf文件的需求。现在的网络中有各种各样的PDF转换工具&#xff0c;有些操作很复杂&#xff0c;有些需要下载软件非常麻烦。接下来&#xff0c;给大家分享一款草最简单还不用下载软件的PPT转PDF&#xff08;https://www.yasuotu.com/p…

黑马程序员JavaWeb开发|案例:tlias智能学习辅助系统(1)准备工作、部门管理

一、准备工作 1.明确需求 根据产品经理绘制的页面原型&#xff0c;对部门和员工进行相应的增删改查操作。 2.环境搭建 将使用相同配置的不同项目作为Module放入同一Project&#xff0c;以提高相同配置的复用性。 准备数据库表&#xff08;dept, emp&#xff09; 资料中包含…

C#基础-空处理

在c#中&#xff0c;值对象是没有办法赋值为null的。比如说&#xff0c;你想要定义一个布尔值&#xff0c;你的赋值数据要么得是true、要么就得是false&#xff0c;默认情况下我们永远没可能给这个布尔赋值为null&#xff0c;即使只是对这个变量进行声明而不初始化数据&#xff…

代码随想录算法训练营第四天| 24. 两两交换链表中的节点、19.删除链表的倒数第N个节点面试题 02.07. 链表相交、142.环形链表II

文档讲解&#xff1a;虚拟头节点&#xff0c;三指针&#xff0c;快慢指针&#xff0c;链表相交&#xff0c;环形链表&#xff0c; 技巧&#xff1a; 1、对于指针的操作要画图&#xff0c;明确步骤后好做了 2、使用虚拟头节点可以避免对头节点单独讨论&#xff0c;且方便对头节点…

详解CAS及ABA问题

&#x1f308;&#x1f308;&#x1f308;今天给大家分享的是 CAS 问题。 清风的CSDN博客 &#x1f6e9;️&#x1f6e9;️&#x1f6e9;️希望我的文章能对你有所帮助&#xff0c;有不足的地方还请各位看官多多指教&#xff0c;大家一起学习交流&#xff01; ✈️✈️✈️动动…