深入理解JavaScript系列(2):揭秘命名函数表达式(2)
// 千万别这样做! // 因为有的浏览器会返回first的这个function,而有的浏览器返回的却是第二个 if (true) { function foo() { return 'first'; } } else { function foo() { return 'second'; } } foo(); // 相反,这样情况,我们要用函数表达式 var foo; if (true) { foo = function() { return 'first'; }; } else { foo = function() { return 'second'; }; } foo();复制代码
函数声明的实际规则如下:
函数声明只能出现在程序或函数体内。从句法上讲,它们 不能出现在Block(块)({ ... })中,例如不能出现在 if、while 或 for 语句中。因为 Block(块) 中只能包含Statement语句, 而不能包含函数声明这样的源元素。另一方面,仔细看一看规则也会发现,唯一可能让表达式出现在Block(块)中情形,就是让它作为表达式语句的一部分。但是,规范明确规定了表达式语句不能以关键字function开头。而这实际上就是说,函数表达式同样也不能出现在Statement语句或Block(块)中(因为Block(块)就是由Statement语句构成的)。
函数语句
在ECMAScript的语法扩展中,有一个是函数语句,目前只有基于Gecko的浏览器实现了该扩展,所以对于下面的例子,我们仅是抱着学习的目的来看,一般来说不推荐使用(除非你针对Gecko浏览器进行开发)。
1.一般语句能用的地方,函数语句也能用,当然也包括Block块中:
if (true) { function f(){ } } else { function f(){ } }复制代码
2.函数语句可以像其他语句一样被解析,包含基于条件执行的情形
if (true) { function foo(){ return 1; } } else { function foo(){ return 2; } } foo(); // 1 // 注:其它客户端会将foo解析成函数声明 // 因此,第二个foo会覆盖第一个,结果返回2,而不是1复制代码
3.函数语句不是在变量初始化期间声明的,而是在运行时声明的——与函数表达式一样。不过,函数语句的标识符一旦声明能在函数的整个作用域生效了。标识符有效性正是导致函数语句与函数表达式不同的关键所在(下一小节我们将会展示命名函数表达式的具体行为)。
// 此刻,foo还没用声明 typeof foo; // "undefined" if (true) { // 进入这里以后,foo就被声明在整个作用域内了 function foo(){ return 1; } } else { // 从来不会走到这里,所以这里的foo也不会被声明 function foo(){ return 2; } } typeof foo; // "function" 复制代码
不过,我们可以使用下面这样的符合标准的代码来模式上面例子中的函数语句:
var foo; if (true) { foo = function foo(){ return 1; }; } else { foo = function foo() { return 2; }; }复制代码
4.函数语句和函数声明(或命名函数表达式)的字符串表示类似,也包括标识符:
if (true) { function foo(){ return 1; } } String(foo); // function foo() { return 1; }复制代码
相关新闻>>
- Javascript 兼容 IE6、IE7、FF 的“加入收藏”“设为首页”
- 好好学一遍JavaScript 笔记(一)——基础中的基础
- 好好学一遍JavaScript 笔记(二)——encode、数组、对象创建
- 好好学一遍JavaScript 笔记(三)——StringBuffer、prototype
- 好好学一遍javaScript 笔记(四)——Attribute、HTML元素、文档碎
- 好好学一遍JavaScript 笔记(五)——正则表达式基础
- 好好学一遍JavaScript 笔记(六)——正则表达式基础二
- 好好学一遍JavaScript 笔记(七)——RegExp对象与常用正则
- 好好学一遍JavaScript 笔记(八)——冒泡型事件、捕获型事件
- JavaScript详解
- 发表评论
-
- 最新评论 更多>>