首页
function对象的创建
function对象的创建
版权声明:本文为原创内容,转载请声明出处。
原文地址:http://www.excelib.com/article/189/show

ES中创建function主要有三种方法:函数声明、函数表达式以及使用Function来创建,下面学生就带大家分别来学习。

函数声明

函数声明的结构如下

function  函数名(参数) {函数体}

函数声明一共由四部分组成:最前面的是function关键字,这个是固定不变的;第二部分是函数名;第三部分是一对圆括号,里面存放函数的参数,可以为空,也可以有多个,如果有多个需要使用逗号分隔;最后一部分是用花括号包含的函数体,里边存放函数具体执行的逻辑。

比如下面的语句可以定义一个log函数

1
2
3
function log(msg) {
     console.log(msg);
 }

这个函数的函数名叫log,有一个msg参数,函数体的内容是将参数打印到控制台,使用这个函数来打印日志就比直接调用console.log(msg)要简单。

函数表达式

函数表达式的结构是将函数声明中的函数名去掉,然后将创建的结果赋值给一个变量,比如上面的log函数使用函数表达式创建的方式为

1
2
3
var log =  function(msg) {
     console.log(msg);
 }

这样创建出来的log函数和前面通过函数声明创建出来的log函数在使用上没有区别。


使用Function创建

Function(开头的F是大写)是ES中的一个内置的特殊的function,我们可以在FireBug通过下面的代码来查看

1
console.log(typeof Function);    //function

Function是一个特殊的function,使用它新建的对象并不是object类型,而是function类型,他可以有多个参数,类型都是字符串类型,其中最后一个参数的内容就是所创建function对象的函数体,前面的参数是所创建function的参数,他的返回值可以赋值给一个变量,作为函数名来使用。结构如下

var funcName = new Function("参数1", "参数2", ..., "函数体");

比如我们上面的log方法如果使用Function可以这样创建

1
var log = new Function("msg""console.log(msg);");

使用Function所创建的function跟前面两种是不一样的,他将函数体放到了字符串参数中,这样首先是书写不方便;另外,在创建的时候编译器也不会检查其正确性,如果有错误只有在调用的时候才能发现,比如将上面代码中的“console”写成“consle”,在创建的时候是不会报错的;而且使用Function定义的function效率也比前两种低,所以这种方法使用的比较少。

不同创建方法之间的关系

因为Function(第三种创建方法)使用的非常少,所以学生这里主要为大家介绍前两种创建方法之间的关系。

在ES中所有的数据只有两种存在形式,要么是对象的属性要么就是变量(学生会在后面详细解释这两种存在形式的区别),函数也不例外,而无论是对象的属性还是变量都是名值对的结构,所以函数也应该是这种名值对的结构。

函数声明

函数表达式可以很容易看明白这一点,他将所创建的对象赋值给了一个变量。其实在函数声明方式创建函数的时候ES在背后也自动帮我们做了这件事情,他首先创建了函数对象,然后又创建了跟函数名同名的变量并将创建出来的函数赋值给了这个变量,所以前面通过函数声明创建的log函数等价于下面的语句

1
2
3
var log = function log(msg) {
     console.log(msg);
 }

这一点使用FireBug可以清楚地看到,我们先在FireBug中执行下面的代码

1
2
function F(a){}
var f = F;

FireBugDOM选项卡中就可以看到图1所示结构

图1

从图中可以看出这里的函数声明语句会首先创建了名叫F的函数,然后将其值赋给了同名的F变量,在我们定义f变量的语句中f也指向了创建出来的F函数对象,这时内存中的结构如图2所示

图2

为了让大家理解的更加清楚,我们可以将F设置为null,然后使用f调用F函数对象,如果F是function本身的话我们将F设置为null之后f也应该不能再调用了,如果将F设置为null之后f还可以调用函数,那么就说明F只是函数的一个引用,或者说是一个和f一样的变量。修改后的代码如下

1
2
3
4
5
6
function F(a){
     console.log(a); 
var f = F; 
F = null
f("hello function");           //输出hello function

从结果可以看出,将F设置为null之后f还可以来调用函数,也就是说函数声明方式创建function时会自动创建一个同名的变量返回给我们使用,上面例子中的F就是这样的变量,将F设置为null后的内存模型如图3所示

图3

函数表达式

上面说的是通过函数声明创建的function对象,通过函数表达式来创建其实道理也差不多,只是他会创建一个匿名函数然后再赋值给了定义的变量,比如我们执行如下代码

1
2
var anonymous = function (b) {}
var anony = anonymous;

他在FireBug中的结构如图4所示(注意和图1之间的区别)

4

这时anonymousanony两个变量都指向了一个匿名函数,内存结构如下图5所示

5


总结

其实函数的创建主要就三部分:函数名、参数、函数体,他们又可以分为两部分,其中参数和函数体属于函数对象自身,而函数名是获取函数对象的一个引用,或者可以理解为一个函数对象的快捷方式。函数表达式会直接将所创建的函数返回给一个快捷方式,而函数声明会在内部自动创建一个和函数名同名的快捷方式。