JavaScript 函数定义方式

函数的定义

通俗的来讲,函数是由事件驱动的或者当它被调用时执行的可重复使用的代码快。它是 JavaScript 语言一个即重要又复杂的组成部分,任何一个 JavaScript 框架,如 Dojo、jQuery 等都是有成百上千个函数组成的。函数的使用不仅提高了代码本身的可读性,也为它的扩展提供了可能,同时还降低了维护成本,加快 web 项目的开放进度;尤其是在多人参与的敏捷开发中。

通常函数的定义是通过 function 语句实现的:

清单 1.函数定义

1

2

3

function funcname([arg1[,arg2……]]){

  statements

}

funcname 是要定义的函数名,是一个标识符,而不是字符串或者表达式;紧跟函数名后面的是用括号括起来的参数列表,参数之间用逗号隔开;最后,也是这个函数的核心部分:函数体,它是由一行或者多行代码组成并且是用大括号括起来的。

函数定义描述的是一个静态的程序结构,当 JavaScript 解析器遇到一个函数定义时,它就被解析并存储构成函数体的语句,然后定义一个和该函数名同名的全局或者某个对象属性来保存。当该函数被调用时,里面的函数体才真正的被执行。如:

清单 2

1

2

3

4

5

alert(typeof f)//显示 function,而不是 undefined

function f(x,y){

  alert(x+y);

}

f(2, 3) //显示 5

函数定义方式之 Function()构造函数

定义一个函数,最为普遍的是直接使用 function 关键字来定义,又称函数声明式(function declaration),如上面定义的 f 函数,但是 function 语句并非是定义函数的惟一方法。在 ECMAScript v1 和 JavaScript v1.1 中,还可以使用 Function () 构造函数和 new 运算符动态地定义函数,如下:

1

var myfunc = new Function ('x', 'y', 'alert(x+y)');

这行代码创建了一个新函数,该函数和下面使用 function 方法定义的函数是等价的:

清单 3.

1

2

3

function myfunction(x, y){

  alert(x+y);

}

Function () 定义中,前面两个是参数,参数可以是任意多个字符串;第三个是函数体,可以包含任何 JavaScript 语句,语句之间用分号隔开。如果没有参数,传一个函数体即可。由于传递给 Function () 函数中,没有一个字符串是用来声明函数名的,所以它是一个匿名函数。

使用 Function()构造函数来定义函数允许我们动态的来定义和编译一个函数,而不是限定在 function 预编译的函数体中。但同时也会带来负面影响,因为每次调用这个函数都要对它进行编译,对性能有一定的影响,尤其是在循环体中。

函数定义方式之函数直接量

函数定义的第三种方式是函数直接量,ECMAScript v3 定义了函数直接量,JavaScript 1.2 实现了它。函数直接量是一个表达式,它即可以定义一个匿名函数,也可以定义一个带函数名的函数:

清单 4.

1

2

3

4

5

6

7

8

9

10

var sum = function(a, b){

  return a+b;

}

var f = function fact(x){

  if(x<= 1){

    return 1;

  }else{

return x * fact(x-1);

  }

}

函数直接量和使用 Function()构造函数来创建函数的方法非常相似,因为两种方法都是通过 JavaScript 的表达式创建的,而不是由语句创建的;所以使用他们的方式也更灵活,尤其是那些只使用一次,而且不需要命名的函数。比如把它传递给其他的函数:

清单 5.

1

2

3

4

5

6

var desc = function(a, b){

  return a<b;

}

var a = [2,1,4,3,6,7];

a.sort(desc);// 把desc函数当作参数传给数组的sort方法

alert(a.join(','))// 输出7,6,4,3,2,1

区别

三种方式的区别,可以从作用域、效率以及加载顺序来区分。首先,从作用域上来说,函数声明式和函数直接量使用的是局部变量,而 Function()构造函数却是全局变量:

清单 6.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

var y = 'global';

function a(){

  var y = 'local a';

  return y;

}

alert(a());//显示'local a'

var b = function(){

  var y = 'local b';

return y;

}

alert(b()) //显示'local b'

function c(){

  var y = 'local c';

  return new Function('return y');

}

alert(c()());//显示'global',因为Function()返回的是全局变量y,而不是函数体内的局部变量。

其次是执行效率上来说,Function()构造函数的效率要低于其他两种方式,尤其是在循环体中,因为构造函数每执行一次都要重新编译,并且生成新的函数对象:

清单 7.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

var start = new Date().getTime();

for(var i=0; i<10000000; i++){

  var f = new Function(‘a’, ‘b’, ‘return a+b’);

  f(i, i+1);

}

var end = new Date().getTime();

alert(end-start);//结果显示~11s

 

start = new Date().getTime();

var f = function(a, b){

  return a+b;

}

for(var i=0; i<10000000; i++){

  f(i, i+1);

}

end = new Date().getTime();

alert(end-start);//结果显示~7s

由此可见,在循环体中,函数直接量的执行效率是 Function()构造函数的 0.6 倍。所以在 Web 开发中,为了加快网页加载速度,提高用户体验,我们不建议选择 Function ()构造函数方式来定义函数。

最后是加载顺序,function 方式(即函数声明式)是在 JavaScript 编译的时候就加载到作用域中,而其他两种方式则是在代码执行的时候加载,如果在定义之前调用它,则会返回 undefined

清单 8.

1

2

3

4

5

6

7

8

9

10

11

12

<code>alert (typeof f)//显示 function

alert (typeof c)//显示 undefined,因为 c 还没有定义

alert (typeof d)//显示 undefined,因为 d 还没有定义

function f(){

  return true

}

var c = function(){

  return true;

}

alert(typeof c);//显示 function,上面已经定义,所以不是 undefined

var d = new Function(‘return true’)

alert(typeof d);//显示 function,上面已经定义,所以不是 undefined</code>

相关主题

  查看 HTML5 专题,了解更多和 HTML5 相关的知识和动向。

from: https://www.ibm.com/developerworks/cn/web/1406_dengxb_jsfunction/index.html 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值