1.声明函数和函数表达式浏览器
function foo(){} // 声明,由于它是程序的一部分函数
var bar = function foo(){}; // 表达式,由于它是赋值表达式的一部分spa
new function bar(){}; // 表达式,由于它是new表达式对象
(function(){作用域
function bar(){} // 声明,由于它是函数体的一部分字符串
})();io
--------------------------------------------------function
function foo(){} // 函数声明变量
(function foo(){}); // 函数表达式:包含在分组操做符内程序
try {
(var x = 5); // 分组操做符,只能包含表达式而不能包含语句:这里的var就是语句
} catch(err) {// SyntaxError
}
-----------------
try {
{
"x": 5
}; // "{" 和 "}" 作解析成代码块
} catch (err) {
// SyntaxError
}
({
"x": 5
}); // 分组操做符强制将"{" 和 "}"做为对象字面量来解析、
表达式和声明存在着十分微妙的差异,首先,函数声明会在任何表达式被解析和求值以前先被解析和求值,即便你的声明在代码的最后一行,它也会在同做用域内第一个表达式以前被解析/求值,参考以下例子,函数fn是在alert以后声明的,可是在alert执行的时候,fn已经有定义了:
alert(fn());
function fn() {
return 'Hello world!';
}
另外,还有一点须要提醒一下,函数声明在条件语句内虽然能够用,可是没有被标准化,也就是说不一样的环境可能有不一样的执行结果,因此这样状况下,最好使用函数表达式:
// 由于有的浏览器会返回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();
2.函数语句
函数语句不是在变量初始化期间声明的,而是在运行时声明的——与函数表达式同样。不过,函数语句的标识符一旦声明能在函数的整个做用域生效了。标识符有效性正是致使函数语句与函数表达式不一样的关键所在
// 此刻,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;
};
}
----------------------------
.函数语句和函数声明(或命名函数表达式)的字符串表示相似,也包括标识符:
if (true) {
function foo() {
return 1;
}
}
String(foo); // function foo() { return 1; }
函数语句覆盖函数声明的方式不正确。在这些早期的实现中,函数语句不知何故不能覆盖函数声明:
function foo() {
return 1;
}
if (true) {
// 用函数语句重写
function foo() {
return 2;
}
}
foo(); // FF3如下返回1,FF3.5以上返回2
// 不过,若是前面是函数表达式,则没用问题
var foo = function() {
return 1;
};
if (true) {
function foo() {
return 2;
}
}
foo(); // 全部版本都返回2
3.命名函数表达式