申明式函数与表达式函数
函数作为js中的对象可以分为申明式函数和表达式函数。
1、表达式函数指的是作为赋值运算,以及不带函数名称的那些函数,除此之外 皆为申明函数。
function fun1(){//申明函数
}
var fun2 = function(){//表达式函数,因为作为赋值
}
(function (){//表达式函数,因为是匿名函数
})()
var fun3 = function fun4(){//还是表达式函数,因为还是作为赋值预算
}
function fun5(){//这里的fun5,fun6都是申明函数
function fun6(){
}
}
}
var fun2 = function(){//表达式函数,因为作为赋值
}
(function (){//表达式函数,因为是匿名函数
})()
var fun3 = function fun4(){//还是表达式函数,因为还是作为赋值预算
}
function fun5(){//这里的fun5,fun6都是申明函数
function fun6(){
}
}
2、申明函数创建于进入新的执行环境的时候,也就是在执行代码之前就会先创建,而表达式函数创建于执行代码的时候
//以下各代码分开,上下没关系
//代码1
alert(typeof fun1);//输出function,因为在执行alert时fun1函数已经创建
function fun1(){
}
//代码2
fun1();//输出code2,两函数都于与解析时创建,只不过下面的因为同名而覆盖了上面的函数
}
function fun1(){
alert('code2');
}
//代码3
fun1();//输出code2
var fun1=function(){
alert('code1');
}
fun1();//输出code1
function fun1(){
alert('code2');
}
//代码1
alert(typeof fun1);//输出function,因为在执行alert时fun1函数已经创建
function fun1(){
}
//代码2
fun1();//输出code2,两函数都于与解析时创建,只不过下面的因为同名而覆盖了上面的函数
function fun1(){
alert('code1');}
function fun1(){
alert('code2');
}
//代码3
fun1();//输出code2
var fun1=function(){
alert('code1');
}
fun1();//输出code1
function fun1(){
alert('code2');
}
下面再来解释下什么是进入一个新的执行环境,所谓新的执行环境,是全局执行环境即刚加载文档的时候的全局执行环境,或者进入一个函数时的环境,没当进入一个新的执行环境都会创建新的可变对象,执行环境中申明的函数也会创建新的, 看下面例子
//代码1
function fun1(){
fun2(){
}
return fun2;
}
var objf1=fun1();
var objf2=fun1();
alert(objf1===objf2);//输出false,可见两次返回的内部函数都是新建的
//代码2
function fun1(){
this.fun=function fun2(){
}
}
var objf1=new fun1();
var objf2=new fun1();
alert(objf1.fun===objf2.fun);//输出false,两次返回的内部函数都是新建的,如果你认为是new 的缘故看代码3
//代码3
function fun1(){
this.fun=function fun2(){
}
return this.fun;
}
var obj=new Object();
alert(fun1.call(obj)===fun1.call(obj));//输出false
function fun1(){
fun2(){
}
return fun2;
}
var objf1=fun1();
var objf2=fun1();
alert(objf1===objf2);//输出false,可见两次返回的内部函数都是新建的
//代码2
function fun1(){
this.fun=function fun2(){
}
}
var objf1=new fun1();
var objf2=new fun1();
alert(objf1.fun===objf2.fun);//输出false,两次返回的内部函数都是新建的,如果你认为是new 的缘故看代码3
//代码3
function fun1(){
this.fun=function fun2(){
}
return this.fun;
}
var obj=new Object();
alert(fun1.call(obj)===fun1.call(obj));//输出false
表达式函数是无法作为可变对象的属性的,除非赋值引用给一个可变对象的属性,否则外界将无法访问
var fun1 = function fun2(){
return arguments.callee;
}
alert(typeof fun2);//按标准应该是undefined,因为是表达式函数不能于外界访问,firefox,chrome都支持,不过由于IE的特例,目前6、7、8都能访问到,IE9已改正,
alert(typeof fun1);//function
alert(fun1===fun2);//报错,IE9以下输出false
alert(fun1()===fun2());//报错,IE9以下输出false,
alert(fun1===fun2());//报错,IE9以下输出true,
return arguments.callee;
}
alert(typeof fun2);//按标准应该是undefined,因为是表达式函数不能于外界访问,firefox,chrome都支持,不过由于IE的特例,目前6、7、8都能访问到,IE9已改正,
alert(typeof fun1);//function
alert(fun1===fun2);//报错,IE9以下输出false
alert(fun1()===fun2());//报错,IE9以下输出false,
alert(fun1===fun2());//报错,IE9以下输出true,
上面如果是IE6,7,8并没有按照标准来实现,所以仍然能访问到表达式函数fun2