1. 函数的定义
函数体里面是普通的操作语句,不是对象的键值对。
1) 构造函数
(完整详细的写法,但很少用)
|
|
2) 具名函数
(有名字的函数)
|
|
3) 匿名函数
(没有名字的函数,也叫函数表达式)该方法创建的函数sum不会挂到window上
|
|
4) 箭头函数(没有this和arguments属性)
ES6函数定义新语法,sum不会挂到window上,且箭头函数没有this和arguments属性
|
|
每个函数都有返回值,若不写return,默认返回一个undefined,并且返回值是在函数执行时返回
任何函数的构造函数都是自己
2. 函数自身属性
1) name
name这个属性值就是函数本身的名字
2) length
该属性是用来记录函数的形参个数,其属性值是number类型的数字,是形参个数。
3) arguments (箭头函数没有该属性)
在JS中,函数的定义中形参可以不写,在函数调用时可以直接传参,函数会接收传进来的参数,并且依次放进函数的arguments属性里,arguments属性值看似是个数组,但其实说对象更准确,里面数据是按照数组存储的方式存储的,所以arguments就是数组里提到的伪数组。当调用函数test(1,2)时,输出arguments组成如下所示:
|
|
**总结一句就是:**arguments是包含了函数所有参数的伪数组
伪数组不具有数组的公共属性,如push、pop等,如想把伪数组变成数组,可通过Array.from实现。
4) caller
3. 函数公共属性
4. 闭包
4.1 什么是闭包
如果一个函数用到了外部的变量,那么这个函数加这个变量就叫做闭包
未完待续。。。。
5. 调用栈
5.1 什么是调用栈
JS引擎在执行一个函数前,需要把函数所在的环境push到一个数组里,这个数组叫做调用栈。等函数执行完了,就会把环境pop弹出来,然后return到之前的环境,继续执行后续代码
6. 立即执行函数
6.1 来源
在JS中,在函数外用var声明一个变量得到的是一个全局变量,那么如何得到一个局部变量呢?只用通过在函数内声明一个变量才能得到一个局部变量,如下所示:
|
|
那么a就是局部变量了,可是函数fn却是局部变量啊,为了得到一个局部变量,定义了一个全局函数变量,得不偿失,因此,就想到声明一个匿名函数如下:
|
|
那么问题来了,匿名函数咋执行啊,没有名字怎么执行函数得到局部变量啊,因此就将函数的声明和执行统一在一起了,形成:
|
|
但是这样一来,JS认为该语法是错误的,是不对的,经过实验发现,如果在该函数面前加一个操作符,如+、-等就可成功运行了,也可以用括号将其括起来,如下:
|
|
6.2 结论
但经过测试,最保险的方法有如下两种:
-
在前面加感叹号
-
用括号将其包起来,但是要保证前一个语句后有分号隔开。
这样的函数就是立即执行函数。