函数部分分为几个部分:
1.本篇文章介绍函数定义的方法
2.函数内部的对象
http://blog.csdn.net/github_34514750/article/details/51336321
3.函数属性和方法
http://blog.csdn.net/github_34514750/article/details/51336518
4.IIFE立即调用函数表达式
http://blog.csdn.net/github_34514750/article/details/52883401
1.创建函数的方法
创建函数的方法是函数声明,函数表达式,通过函数构造器创建
函数声明
function 函数名称 (参数:可选){ 函数体 }
function foo(){} // 声明,因为它是程序的一部分
(function(){
function bar(){} // 声明,因为它是函数体的一部分
})();
函数表达式
function 函数名称(可选)(参数:可选){ 函数体 }
无函数名的肯定是函数表达式
var bar = function foo(){}; // 表达式,因为它是赋值表达式的一部分,虽然FE赋值给了一个变量(也就是参数),函数将该表达式保存在内存中,并通过变量名来访问(因为变量影响变量对象)
new function bar(){}; // 表达式,因为它是new表达式
(function foo(){}); // 函数表达式:包含在分组操作符内,是因为括号 ()是一个分组操作符,它的内部只能包含表达式
// 在数组初始化器内只能是表达式
[function bar() {}];
// 逗号也只能操作表达式
1, function baz() {};
函数构造器创建
既然这种函数对象也有自己的特色,我们将它与FD和FE区分开来。其主要特点在于这种函数的[[Scope]]属性仅包含全局对象;
//函数bar的[[Scope]]属性不包含foo上下文的Ao——变量”y”不能访问,变量”x”从全局对象中取得。
var x = 10;
foo();
function foo() {
var x = 20;
var y = 30;
var bar = new Function('console.log(x); console.log(y);');
bar(); // 10, "y" 未定义
}
函数声明和函数表达式的区别
1.函数声明FD在进入上下文阶段创建,在代码执行阶段就已经可用了
函数表达式则是在代码执行阶段创建
—所以函数声明可以提升,但是函数表达式无函数声明提升的特性
sayName();//Name
function sayName(){
alert("Name");
}
sayName();//报错,函数不存在
var sayName = function(){
alert("Name");
}
2.函数声明影响变量对象VO,也就是存储在上下文的VO中的变量对象
函数表达式不影响变量对象VO,不存在于变量对象中(那样意味着既不可能通过名称在函数声明之前调用它,也不可能在声明之后调用它)。但是,FE在递归调用中可以通过名称调用自身。
// FE在定义阶段之前不可用(因为它是在代码执行阶段创建)
alert(foo); // "foo" 未定义
(function foo() {});
// 定义阶段之后也不可用,因为他不在变量对象VO中
alert(foo); // "foo" 未定义
(function foo(bar) {
if (bar) {
return;
}
foo(true); // "foo" 是可用的,因为递归调用中可以通过名称调用自身
})();
// 在外部,是不可用的
foo(); // "foo" 未定义
//表达式,因为它是赋值表达式的一部分,虽然FE赋值给了一个变量(也就是参数),函数将该表达式保存在内存中,并通过变量名来访问(因为变量影响变量对象)
var foo = function () {
alert('foo');
};
foo();
3.函数声明只能出现在程序或函数体内。从句法上讲,它们 不能出现在表达式或者Block(块)({ … })中,例如不能出现在 if、while 或 for 语句中。因为js无块级作用域,只有函数和全局作用域。
函数表达式则在源码中须出现在表达式的位置
// 函数可以在如下地方声明:
// 1) 直接在全局上下文中
function globalFD() {
// 2) 或者在一个函数的函数体内
function innerFD() {}
}
// 千万别这样做!
// 因为有的浏览器会返回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();
函数表达式的有优点 – 不污染全局变量
//在代码执行阶段通过条件语句进行创建FE,不会污染变量对象VO。
var foo = 10;
var bar = (foo % 2 == 0
? function () { alert(0); }
: function () { alert(1); }
);
bar(); // 0