函数是可以通过外部代码调用的一个“子程序”(或在递归的情况下由内部函数调用),JavaScript 函数是是Function
对象,可以像任何其他对象一样具有属性和方法;一个函数形成一个单独的作用域
定义函数方式
声明式
function test(param1,param2,...){}
表达式
var test= function(param1,param2,...){}
函数生成器声明(generator函数)
是一种异步编程解决方案,返回一个暂停状态的generator对象,Generator函数有两个特征,通过function* 语句,和函数内部使用的yield 表达式,yield定义函数不同的状态(暂停函数执行的标志);
function* createGenerator(param1,param2,...){
}
函数的执行通过调用遍历器对象的next()方法,该方法会返回一个对象,有两个属性,一个是当前返回值,一个是执行状态boolean ,如果函数没有return语句,那么执行到函数结尾则会返回undefined默认值;
next()方法可以传递一个参数,参数会被当成会上一条语句的返回值(记得是yield语句的返回值),yield的返回值总是undefined,因此最后的结果时NaN
箭头函数表达式
(param1,param2,...)=>{}
适合需要使用匿名函数的地方,不能用作构造函数,只有一个参数时,圆括号可以省略;
param=>{}
箭头函数参数解构与普通函数一样
函数体加括号返回对象字面量表达式;箭头函数只有一条返回语句时,可以直接省略return,也就是说加了{}的箭头函数和普通代码块一样,需要写return语句才有返回值,不加{} 会将后边语句作为返回值
构造函数
通过new 关键字创建
new function(){}
函数参数
调用函数时,传递给函数的值被称为函数的实参(值传递),对应位置的函数参数名叫作形参。在进行值传递时,传递的值会被复制给一个局部变量(命名参数,也就是arguments对象中的一个元素),也就是说,值为基本类型,那么实参和形参是两个独立的内存空间,如果是引用类型,那么值为一个指向同一内存空间的地址引用;比如下面例子:
在函数传参时,参数的个数不定,最多255个,当我们定义一个函数需要传递参数时,在调用时不管如何传参函数都能调用成功,这是js中函数命名参数没有函数签名这一规则,实在程序运行时自动确定(函数签名就是定义函数或方法的输入输出,可包含参数及参数类型、返回值及类型、可能传回抛出的异常等。在调用时,解析器会验证调用是否与签名保持一致。(函数重载))。
js中函数参数都会被保存在arguments对象中(类似数组,但不是数组);arguments对象是所有非箭头函数的局部变量,可以通过arguments[0],arguments[1],....访问函数参数的第一个,第二个......
函数参数默认及解构
以往我们通过给参数设定默认值的时候,通常都是这样做的:
es6中我们可以直接在参数中直接赋默认值:
函数参数解构同对象解构一样,属性名保持一致:
函数提升
generator函数和声明函数会有函数提升行为 整个函数体被提升到作用域的最开始位置,因此不管先定义或后定义都能调用成功,表达式提升的是变量,而非函数体,函数体是赋值过程,等运行到赋值语句时,函数才可以被调用