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

简言

学了这么久的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就算玩出花来,也可以有条理性。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

微机原理常考简答题(二)

一,简述8086CPU响应可屏蔽中断的条件及过程。 CPU响应可屏蔽中断的条件是有中断请求,中断标志IF1开中断,现行指令执行结束。 CPU响应可屏蔽中断的过程:CPU在INTR引脚上接到一个中断请求信号,如果此时IF1,并…

group by 查询慢的话,如何优化?

1、说明 根据一定的规则,进行分组。 group by可能会慢在哪里?因为它既用到临时表,又默认用到排序。有时候还可能用到磁盘临时表。 如果执行过程中,会发现内存临时表大小到达了上限(控制这个上限的参数就是tmp_table…

基于完整熵编码系数组的JPEG图像加密方案

论文题目:JPEG image encryption with grouping coefficients based on entropy coding 期刊:Journal of Visual Communication and Image Representation 分区:中科苑三区,老牌图像处理期刊 文章目录 摘要概要整体架构流程实验结…

mac怎么拼图?Mac拼图技巧分享

mac怎么拼图?在Mac上拼图是一种令人愉悦的创意表达方式,可以让你将多张图片巧妙地融合在一起,创造出令人惊叹的艺术品。本文将向你介绍在Mac上进行拼图的几种方法,帮助你轻松实现这一目标。 一、使用Mac内置的预览功能进行拼图 M…

100个GEO基因表达芯片或转录组数据处理之GSE159676(002)

写在前边 虽然现在是高通量测序的时代,但是GEO、ArrayExpress等数据库储存并公开大量的基因表达芯片数据,还是会有大量的需求去处理芯片数据,并且建模或验证自己所研究基因的表达情况,芯片数据的处理也可能是大部分刚学生信的道友…

物联网协议Coap之Core和NetWork简介

目录 前言 一、Coap的Core包 1、Coap对象 2、Message对象 3、Request对象 4、Response对象 二、Coap的NetWork调试 1、UDP运行模式 2、Network消息接收 3、Sender线程发送数据 三、总结 前言 在之前的博文中,对Californium中Coap的实现进行了简要的介绍&a…

IT从业人员如何养生?

目前,电脑对人体生理和心理方面的负面影响已日益受到人们的重视。为此科学使用电脑,减少电脑和网络的危害是十分必要的。好代码网总结了一些it从业人员的保健知识,分享给大家。 一是要增强自我保健意识 工作间隙注意适当休息,一般…

计算机体系结构----缓存一致性/多处理机

本文严禁转载,仅供学习使用。参考资料来自中国科学院大学计算机体系结构课程PPT以及《Digital Design and Computer Architecture》、《超标量处理器设计》、同济大学张晨曦教授资料。如有侵权,联系本人修改。 本文衔接上文计算机体系结构----存储系统 …

秒懂百科,C++如此简单丨第十二天:ASCLL码

目录 必看信息 Everyday English 📝ASCLL码是什么? 📝ASCLL码表 📝利用ASCLL码实现大写转小写 📝小试牛刀 总结 必看信息 ▶本篇文章由爱编程的小芒果原创,未经许可,严禁转载。 ▶本篇文…

ActiveMQ反序列化RCE漏洞复现(CVE-2023-46604)

漏洞名称 Apache ActiveMQ OpenWire 协议反序列化命令执行漏洞 漏洞描述 Apache ActiveMQ 是美国阿帕奇(Apache)软件基金会所研发的一套开源的消息中间件,它支持Java消息服务、集群、Spring Framework等。 OpenWire协议在ActiveMQ中被用于…

2024年 13款 Linux 最强视频播放器

Linux视频播放器选择多样,如榛名、MPlayer、VLC等,功能强大、支持多格式,满足各类用户需求 Linux有许多非常强大的播放器,与windows最强视频播放器相比,几乎丝毫不逊色! 一、榛名视频播放器 榛名视频播放…

基于JAVA的民宿预定管理系统 开源项目

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 用例设计2.2 功能设计2.2.1 租客角色2.2.2 房主角色2.2.3 系统管理员角色 三、系统展示四、核心代码4.1 查询民宿4.2 新增民宿4.3 新增民宿评价4.4 查询留言4.5 新增民宿订单 五、免责说明 一、摘要 1.1 项目介绍 基于…

【LabVIEW FPGA入门】使用CompactRIO进行SPI和I2C通信

NI提供了 SPI and I2C Driver API:下载SPI and I2C Driver API - NI 该API使用FPGA数字I / O线与SPI或I2C设备进行通信。 选择数字硬件时,要考虑三个选项: NI Single-Board RIO硬件可同时使用SPI和I2C驱动程序。NI 9401 C系列模块与SPI驱动程…

NODE笔记 1 http模块

简单的http模块使用 文章目录 前言 node 提供了 http 模块,首先需要简单的介绍http http协议(超文本传输协议),在web和网络领域都十分重要。在客户-服务通讯的请求响应中,报文大都是基于http。 可以先新建一个简单的…

美力AI变革:生成式AI在美妆和时尚领域的巨大改变

美妆AI技术解决方案提供商—玩美移动于今日发布最新全球趋势报告:《生成式AI在美妆和时尚领域的巨大改变》,就生成式AI在美妆和时尚行业的崛起,为品牌商提供了富有洞见的深入分析。该报告分析了来自玩美移动屡获殊荣的玩美系列APP应用套件的大…

imx6ull基于yocto工程的l汇编点亮ed

通过汇编点亮led 在裸机状态下通过汇编点亮led,即没有操作系统,(uboot kernel rootfs 都不需要实现)。 led点亮原理 1.GPIO复用 根据原理图,找到led对应的引脚(pin),复用为GPIO(只有GPIO才能…

力扣热题100

排序 快速排序 #include <iostream> #include <vector> using namespace std;// 快速排序函数&#xff0c;传入引用&#xff0c;以便修改原始数组 void quick_sort(vector<int>& q, int l, int r) {// 边界条件&#xff1a;如果左边界大于等于右边界&am…

胶囊-药品广告数据库-解锁药品营销市场

随着医药技术的不断进步&#xff0c;药品市场的竞争也日益激烈&#xff0c;而「广告营销」一直以来都是医药企业发展过程中的重要环节&#xff0c;越来越多的药企意识到药品广告在品牌传播和营销方面的巨大潜力。 而一个好的药品广告投放方案往往需要进行全方位的市场调研&…

Linux Debian12使用VSCode和Python搭建flask开发环境

一、安装VSCode 在Linux Debian12系统上安装VSCode教程可以参考网上相关教程。 二、安装Python 打开VSCode&#xff0c;安装python和python扩展包&#xff0c;如下图所示&#xff1a; 三、创建Python虚拟环境 1.新建文件夹testFlask 2.用vscode打开文件夹testFlask&#xf…

Java副本的概念

在Java中&#xff0c;"副本"&#xff08;copy&#xff09;一词可以用于描述不同的概念&#xff0c;具体取决于上下文。以下是两个常见的用法&#xff1a; 对象的副本&#xff1a;在Java中&#xff0c;当你创建一个对象并将其赋值给另一个变量时&#xff0c;实际上是创…