代码一:
function show(){
alert(12);
return function(){
alert(3);
};
}
alert(show()());
我觉得这段函数应该会报错,因为 下面的show(括号一),返回的是function(){ alert(3); }
那么这个返回的函数后面还有一个括号来调用它,即function(){ alert(3); }()
。
我在全局环境下,写这段代码就会报错,function(){ alert(3); }()
。
请问为什么代码一所示函数就可以正常运行呢?谢谢。
其他地方你的理解是对的,但是你搞错了一点:
show()返回的并不是函数的那一大段,函数是存在内存里的,返回的只是指向这个函数的引用。
说到这里你可能还不太理解什么叫引用,简单来说就是:对象本身存在内存的某个位置,而变量只能持有一个指向这个位置的标记。你可以想一想C语言里的指针。
这时就好理解了,
show()()
并不是这只是简单的字符串替换,JavaScript并不是这么工作的。
这段代码的实际过程是:在内存中创建匿名函数,将这个函数的引用返回出去。
所以
show()
得到的是对匿名函数的引用x,然后x()
执行了这个匿名函数。所以根本不会有什么错误。
说了这么多题主并不一定能完全理解,所以给出一些代码,题主可以试一试。
这是因为内存中出现了两个长得完全一样的函数,但是他们仍然是两个函数。
进一步:
现在考虑向一个函数传入另一个函数呢?
题主不妨亲自试一试。
上面的代码说明了在JavaScript中,函数和其他的引用类型一样,可以方便地传入另一个函数,被函数返回,当然,传入和返回的都只是对函数的引用,而不是函数本身,更不是函数的那段字符串。
函数表达式有两种,匿名的和具名的:
匿名函数表达式很容易看出来,就是没有名字嘛啊哈哈哈。
具名函数表达式则需要和函数声明语法进行区别:
实际上只有明显的使用上面代码中那种函数声明方式,JS才会把它当作是声明,否则就会当作表达式,比如@qianjiahao 提到的那几种形式:
其他形式可以参考@qianjiahao 的答案。
具名函数表达式(NFE)和函数声明还有一个有意思的区别,就是在NFE中,你可以访问函数名但是不能修改函数名。
例如:
更详细的内容参考我之前的问题:http://segmentfault.com/q/1010000002810093