js 匿名函数_JS从入门到不放弃(三)函数的那点事儿

欢迎来到我的JS从入门到不放弃专题系列文章,更多精彩内容持续更新中,欢迎关注 :)

b4340a0bf9f2c7f3b921c6bca3f8f58a.png

上一小节我通过可视化的方式分享了数组的一些常用的方法的基本使用。

本章节我们来讨论一下JS中函数的基本用法

本章目标

  1. 函数的概念和基本用法
  2. 函数的高级用法
  3. 递归函数的特性和使用

在JS中,函数和方法可以理解一个东西,那么什么是函数呢?

我的理解就一句话,可以复用的代码块,我们通过function关键字来创建一个函数。

一、函数的基本使用

一般来说我们刚学函数的时候,会写下面这样的代码:

fcbc8c30d06700ac2597e6875c40a711.png

这应该是最简单的函数的调用了, 在函数中,我们可传入不同的参数,从而运行出不同的结果。

0d49dad8219f2c365757461cc8f2a8e8.png

好吧,这些基础的相信大家都会了,也不在在这卖弄了。

二、函数的传参和返回值

2d0dd91cd7e9f6fbd7e47bf79a28277c.png

这里涉及在几乎所有的编程语言都有涉及的名词:形式参数和实际参数,那么在本示例中,add方法的定义中,a 和b都是形式参数,我们一般叫形参,那么在实际的调用中,传入的参数1和2我们称之为实际参数,也叫实参。

JS函数的最后,我们可以通过return关键字返回一个结果,这个结果可以是任意类型。

三、函数真实项目中的应用

1、判断一个浏览器是否是微信浏览器,一般来说,浏览器的类型一般都存在JS内置对象window.navigator.userAgent,它返回的就是一个浏览器的信息。

7b7d6b5cc10646ab44f7917b06f3f1e6.png
259b123e89b620e260416b0fe100f5f4.png

划重点:一般来说,我们定义一个函数的方法有两种。

1、function fnName(){},这样去定义的函数满足函数的预加载特性。什么意思?比如

test();

function test(){}

这样去调用是没有问题的,可以这样理解,当JS执行到test方法的时候,会优先去找对应函数的定义,找到了就执行,没有找到就报语法错误。

2、像上面我们定义判断是否是微信浏览器的时候,我是通过var isWeixin= function(){}这样的方式去定义的函数。这种情况我们是将一个函数赋值给一个变量,那么就是遵循变量的规则,即:先定义,再调用。

所以我们在调用isWeixin函数的时候,一定要放在函数变量之后调用。否则会报错

函数的高级用法

1、匿名函数

像我们上面用到的isWeixin方法,我们是通过var isWeixin=function(){}来定义出来的。这里function 后面没有跟函数名,而是直接将函数对象通过赋值的形式赋给了isWeixin变量,这个变量的

类似这种用法,我们在之前的示例中也有体现,比如我们在给一个按钮添加点击事件的时候,

btn.onclick = function(){} 这种用法是我们将一个函数对象赋值给一个对象的属性。

2、函数自执行

看过我之前示例的小伙伴应该都知道,我在写js代码之前,往往会先封装一个闭包的形式。

先()();第一个小括号里面填写一个匿名函数。第二个小括号则表示立即调用这个函数、

像这样

013deba63ccedf0c1219cf8b336fee76.png

我们也可以把第一个小括号变形一个感叹号,就像这样:

51e9079d9d2bca2371a55095d3147b70.png

恩,看到这种写法,相信读过一些知名的类库的源码的都知道,比如jQuery插件的扩展,一般来说都用这种方式来撸。

说明:这里的感叹号也可以是 + 和 - 哦,以后大家看到这路写法应该就知道是什么意思了吧。

3、函数递归(难点)

工作中我总结了递归函数的三大特点:

  1. 函数调用自身
  2. 函数体中必须有一个终止递归的条件
  3. 调用自身的时候一定与第一次调用的实参不一样。否则也会陷入死循环。

为什么要一个终止的条件??可以这样想一下,如果没有终止条件,那么函数自身在不停的调用自己,进入了死循环。这时候一定会导致内存占用过大,直到你的浏览器崩溃!所以在使用递归的时候,一定要分析好。

示例1、求阶乘

84e4e2872158b2f12a6e628b6188a721.png

我们要求一个数的阶乘。先找出循环调用的终止条件,当n=1的时候,阶乘已经乘到了最后一位了,这时候我们只需要将1返回出来即可。

否则当n !== 1的时候,我们要去递归调用函数本身,注意:这时候调用的实参应该是 n-1, 然后将 n-1传入到函数中去,再乘以 n,即可实现函数的递归了。

值得注意的是:该函数中的结果res 可以看成是一个在闭包中的变量,函数本身没有调用完成,它是不会被销毁的,一直存留在内存中,将所以有的结果计算完成后一次性返回。

你可能不知道的函数:我们通过function来定义的函数中,一个arguments对象,它表示的是所有的参数的集合,在这个对象下有一个属性callee,我们来打印一下这个arguments.callee长什么样儿?

de0f23bdb6418ae5b48078063c17ff88.gif

从gif图可以看出来,我们阶乘方法调用了两次,打印了两次的arguments.callee对象,返回的内容就是我们函数本身。

所以我认为严格意义来讲,这种方式不并是算是真正的递归,函数内部本身其实是调用的window对象下的一个方法。

接下来我们来对这个函数进行改造一下。

599bd63de7af8320fa69a9a48de107a7.png

我们通过arguments.callee来实现递归。所以以后看到这个希望大家不再陌生。

示例2:无限级菜单分类的问题

一般来说,我们的网站后台会涉及到很多的菜单,比如我目前的项目中,我自己封装的一个子菜单,就是通过递归来实现多级分类的。

6c35769b1a00afe167279dce547493a7.gif

我这只做了两级菜单

接下来我就利用这些数据利用纯dom和递归来实现一个多层级菜单。先来看我们的菜单数据。

6066c3c0a3219fd00436f20b703c22af.png

还是递归的那三步。

1、找出终止条件

2、自身调用自身

3、调用自身的时候,实参变成了对象的children对象

aa6a31ab1a871f51691acb665bb022b7.png
da27172c40a7fe7230fbde87d2c4da47.png

样式我就没写了。

总结:

1、函数的基本使用,形参实参的基本概念。

2、函数的自执行的基本用法 。

3、递归函数的基本使用以及它的三大特点。

这里是【畅哥聊技术】JS从入门到不放弃相关技术文章,更多精彩内容持续更新中,敬请期待。

未完待续。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值