申明式函数与表达式函数

函数作为js中的对象可以分为申明式函数和表达式函数。

1、表达式函数指的是作为赋值运算,以及不带函数名称的那些函数,除此之外 皆为申明函数。

function fun1(){//申明函数
}
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('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

 表达式函数是无法作为可变对象的属性的,除非赋值引用给一个可变对象的属性,否则外界将无法访问

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,

 上面如果是IE6,7,8并没有按照标准来实现,所以仍然能访问到表达式函数fun2

 

 

 

posted @ 2012-03-21 17:54  自由小菜园  阅读(242)  评论(0编辑  收藏  举报