JavaSript 圆括号的使用
先来看一组通过函数声明来定义的函数:
先附代码:
运行结果如下:
这里我们可以看出:
Ø 若没有加圆括号,则返回的是这个函数的内容
Ø 若加上圆括号,则返回的是函数执行后的内容
因此圆括号的作用是作为函数的调用运算符,如果函数使用return语句给出一个返回值,那么这个返回值就是整个调用表达式的值。否则,调用表达式的值就是undefined.
接下来看一组通过函数表达式定义的函数
先附代码:
运行结果如下图:
对于普通函数的调用,函数的返回值成为调用表达式的值。如果该函数返回时因为解释器到达结尾,返回值就是undefined。如果函数返回时因为解释器执行到一条return语句,返回值就是return之后的函数表达式,如果return语句没有值,则返回undefined.
注意:当方法的返回值是一个对象,这个对象还可以再调用他的方法。这种方法调用系列中(通常称为“链”或者“级联”)每次的调用结果都是另外一个表达式的组成部分。
注意:JS中function是对象。
函数的自调用
首先看一个匿名函数的自调用
先附代码:
输出结果:
也就是说自调用会执行函数里面的代码。
再看两例代码对比,来理解闭包这个概念
代码1: 代码2:
运行结果如下:
代码1: 代码2:
我们来试图理解这句话:
Ø 每次调用JS函数时,都会为之创建一个新的对象用来保存局部变量,把这个对象添加至作用域链中,当函数返回时,就从作用域链中将这个绑定变量的对象删除。如果不存在嵌套的函数,也就没有其他引用指向这个绑定对象,他就会被当作垃圾回收掉。
Ø 如果定义了嵌套的函数,每个嵌套的函数都各自对应一个作用域链,并且将这个作用域链指向一个变量绑定对象。但是如果这些嵌套的函数对象在外部函数中保存下来,那么他们也会和所指向的变量绑定对象一样当作垃圾回收。
Ø 但是如果这个函数定义了嵌套的函数,并将它作为返回值返回或者存储在某处的属性里,这时就会有一个外部引用指向这个嵌套的函数。他就不会被当作垃圾回收,并且它所指向的变量绑定对象也不会被当作垃圾回收。
//上文摘自JS权威指南。
在案例1中,函数add是一个自调用函数。我们将逐句对应解释示例1的运行结果:
12-17 用匿名函数表达式来定义了add函数,需要注意的是这个匿名函数是个自调用函数。
13 设置了counter=0;
14-15 定义了返回function(){ return ++count;}, 也就是说add函数执行的语句为function(){ return ++count;}
执行第一次,我们绘出add的运行期上下文作用链表:
由于可以访问到counter=1 ,add()=1;
执行第二次,继续执行++counter counter=2,add()=2;
执行第三次,继续直接执行++counter counter=3,add()=3
我认为的闭包是这样的,count变量不属于全局变量,但是又在add函数内部被定义成私有变量,于是就规定它为嵌套函数作用域对象的部分,且这个嵌套函数有没有被外部函数所保存,不会被当作垃圾回收。这就是为什么count值被循环利用的原因。
/****************************************************************
案例2的作用域链表
根据JS权威指南的讲解,count变量在外部函数中保存了下来,那么他们也会和所指向的变量绑定对象一样当作垃圾回收。所以作用值会被覆盖。结果一直都是1的原因。