一、function概述
javascript中的函数不同于其他的语言,每个函数都是作为一个对象被维护和运行的。通过函数对象的性质,可以很方便的将一个函数赋值给一个变量或者将函数作为参数传递。
函数对象与其他用户所定义的对象有着本质的区别,这一类对象被称之为内部对象。内置对象的构造器是由JavaScript本身所定义的。
二、function对象的创建
在JavaScript中,函数对象对应的类型是Function,可以通过new Function()来创建一个函数对象,也可以通过function关键字来创建一个对象。
//使用new Function()方式创建
var myFunction=new Function("a","b","return a+b");
//使用function关键字创建
function myFunction(a,b) {
return a + b;
}
用关键字创建对象的时候,在解释器内部,就会自动构造一个Function对象,将函数作为一个内部的对象来存储和运行。从这里也可以看到,一个函数对象 名称(函数变量)和一个普通变量名称具有同样的规范,都可以通过变量名来引用这个变量,但是函数变量名后面可以跟上括号和参数列表来进行函数调用。
new Function()的语法规范如下:
var funcName=new Function(p1,p2,...,pn,body);
参数的类型都是字符串,p1到pn表示所创建函数的参数名称列表,body表示所创建函数的函数体语句,funcName就是所创建函数的名称。可以不指定任何参数创建一个空函数,不指定funcName创建一个匿名函数。
需要注意的是,p1到pn是参数名称的列表,即p1不仅能代表一个参数,它也可以是一个逗号隔开的参数列表,例如下面的定义是等价的:
new Function("a", "b", "c", "return a+b+c")
new Function("a, b, c", "return a+b+c")
new Function("a,b", "c", "return a+b+c")
函数的本质是一个内部对象,由JavaScript解释器决定其运行方式。并且可直接在函数声明后面加上括号就表示创建完成后立即进行函数调用,例如:
var i=function (a,b){
return a+b;
}(1,2);
alert(i);
这段代码会显示变量i的值等于3。i是表示返回的值,而不是创建的函数,因为括号“(”比等号“=”有更高的优先级。
三、匿名函数和有名函数的区别
匿名函数必须先定义后调用,有名函数可以先调用,后定义。
A)匿名(这段语句将产生func未定义的错误)
<script>
func();
var func = function() {
alert(1);
}
< /script>
B)有名(输出1)
<script>
func();
function func() {
alert(1);
}
< /script>
这是因为JS解释器是分段分析执行的。并且,在同一段中,有名函数会优先被分析。并且同名函数后面的覆盖前面的。
而且,下面这段代码也是合法的:
<script>
function myfunc ()
{
alert("hello");
};
myfunc(); //这里调用myfunc,输出yeah而不是hello
function myfunc ()
{
alert("yeah");
};
myfunc(); //这里调用myfunc,输出yeah
</script>
如果要让上述代码的第一次调用输出“hello”,可以将它们分为两段:
<script>
function myfunc ()
{
alert("hello");
};
myfunc(); //这里调用myfunc,输出hello
< /script>
<script>
function myfunc ()
{
alert("yeah");
};
myfunc(); //这里调用myfunc,输出yeah
</script>
下面的代码输出“hello”
<script>
function myfunc ()
{
alert("hello");
};
< /script>
<script>
myfunc(); //输出“hello”
</script>
<script>
function myfunc ()
{
alert("yeah");
};
</script>
下面的代码输出“yeah”
<script>
function myfunc ()
{
alert("hello");
};
< /script>
<script>
function myfunc ()
{
alert("yeah");
};
</script>
<script>
myfunc(); //输出“yeah”
</script>
从上面对段的位置变化导致输出变化很清楚的解释了JS解释器分段分析执行的本质。