函数的核心理念——抽象和封装过程
封装过程:指的是用户只需知道函数名,如何正确的传递参数以及返回值就够了,而内部的逻辑用户无需知道。
抽象:借助抽象,我们才能不关心底层具体的实现/计算过程,而直接在更高层上思考问题。
而函数就是抽象的方式,一个函数就是一个一个完整的行为,函数体内部的语句在执行的时候,函数内部通过条件判断和循环就可以完成非常复杂的逻辑。
函数的执行过程
输入(传参)——计算/处理 ——输出(返回结果,如果有)
函数就是一段完整的代码,函数在执行的过程中,如果没有return
语句(函数结尾如果没有return
语句就是隐含 return undefined
),控制权无法交回被调用的代码。一旦执行到return
时,函数就执行完毕,并将结果返回。
ES6中的Generator
函数除外,Generator
函数的yield
类似return
,可以返还控制权。
JS中的函数
JavaScript中函数定义参数时没有指定参数的数据类型
JavaScript中的函数不会对参数
arguments
进行类型检查JavaScript中的函数不会对
arguments
进行个数检查JavaScript中函数没有重载
对比JAVA的函数
|
|
修饰符
public
修饰了函数getRecord
的可访问性String
说明了存在返回值并且说明了返回值类型int key
说明了参数类型和参数名字
JAVA函数的定义
1、支持重载
2、定义函数时就可以看到函数的访问性(访问控制修饰符)
3、定义函数时就可以看到函数的返回值类型
4、定义函数时就可以看到函数的参数类型
对比Python函数
调用函数的时候,如果传入的参数数量不对,会报TypeError的错误,并且Python会明确地告诉你:abs()有且仅有1个参数,但给出了两个:
|
|
如果传入的参数数量是对的,但参数类型不能被函数所接受,也会报TypeError的错误,并且给出错误信息:str是错误的参数类型:
|
|
Python函数调用
1、拥有对参数个数检查的机制
2、拥有对参数类型检查的机制
集百家所长编写健壮的JS函数
因为js函数没有对实参进行检查的机制,所以我们编写函数就要自己模拟实现这些机制
从Python中得到的感悟
首先,对参数的个数进行检查
利用arguments
参数判断实际传入参数的个数,这也就是说即使函数没有定义参数,也可以拿到参数的值,也是很多js库常使用的手段
- 实现:可选”参数”
|
|
要把中间的参数b
变为“可选”参数,就只能通过arguments
判断,然后重新调整参数并赋值。
其次,检查参数的数据类型
使用条件判断的方式判断参数的是否传递,以及参数是否是期望的值
|
|
从JAVA中得到的感悟
JAVA中的函数从函数的定义就可以看到函数的参数类型,是否有返回值和返回值类型
所以为了编写可维护的JavaScript函数,我们可以利用注释和规范的命名实现对函数的描述。
- 利用函数名描述函数的功能
- 利用参数名描述参数是什么,利用注释描述参数的数据类型
- 利用返回值描述结果是什么,利用注释描述返回值的数据类型
- 或者写一段完整注释包括:描述函数的目的,功能,参数和参数类型,返回值和返回值类型
模拟函数重载
函数重载:函数名相同,参数的个数和类型不同,实现不同的功能。
模拟重载:利用条件判断判断参数的个数和参数的类型,来实现重载。
参考: