日期:2014-05-16 浏览次数:20407 次
在这篇文章中,将会介绍一些function的知识,比如function的使用,变量作用域,匿名函数,回调,自执行函数,内部函数,闭包等相关的知识。其中,闭包的知识会在下一次的文章中介绍。
javascript是非常灵活的语言。
比如,定义一个函数
?
function sum(a, b) { var c = a + b; return c; }
?
执行sum(1,2)得到3,
执行sum(1),由于javascript允许少传参数,所以后面一个参数将被设成undefined,所以得到NaN,
执行sum(1,2,3,4,5,6),javascript也允许多传参数,后面多余的参数将会被忽略,所以得到3。
可见javascript是非常灵活的。
另外,当创建一个function的时候,javascript会自动创建一个叫做arguments的数组,里面包含了所以参数。
?
function args() { return arguments; }
?
args(); // [] args( 1, 2, 3, 4, true, 'ninja'); // [1, 2, 3, 4, true, "ninja"]?
?
在javascript中,变量不是被定义在一个代码块里面的,而是在一个function里面。也就是说,如果在function内部定义一个临时变量,那么在function外面是没法访问到的,然而将变量定义在一个if或者for代码块里面,在代码块外面是可以访问得到的。如果在任何function外部定义变量,那么这个变量就是全局变量,全局变量在任何function里面都是可以访问得到的。下面我们来看一下例子:
?
var global = 1; function f() { var local = 2; global++; return global; } f(); // 2 local; // ReferenceError: local is not defined
?
我们看到,在函数f里面成功访问到了global变量。但是在函数外部,访问不到local变量。再看下面的代码:
?
function f() { if(true){ var local = 0; } local++; return local; } f(); // 1
?
可以发现,local变量并不是出了if块就不能被访问了。在代码块外面同样可以访问。由此看来javascript的变量的作用域是函数级的,不是块级的。
另外,值得一提的是,如果在函数中定义变量时,没用用var来声明,那么这个变量会被定义为全局变量。看下面代码:
function f() { local=2; } local; // ReferenceError: local is not defined f(); // undefined local; // 2
?
可以发现,在f()函数被调用前,local变量是不存在的,调用后,local可以在函数外部被访问,成为全局变量。
因此,在我们平时开发中,应该尽量用var来定义变量。避免定义全局变量,可以想象多个人在一个脚本中对一个全局变量操作,是相当难控制的。
在一个函数中,定义了一个和外部全局变量同名的变量是,在函数内,局部变量的优先级高于全局变量。为了直观一点,看下面的代码:
?
var a = 123; function f() { alert(a); var a = 1; alert(a); } f();
?
这段代码并不像你所想的一样,第一个alert弹出123,第二个alert弹出1,而是分别弹出undefined和1。这正是因为在函数内部,局部变量的优先级高于全局变量,所以,局部变量会覆盖所有同名的全局变量。
在javascript中,函数也是数据,定义函数可以有以下两种方式:
?
function f(){ return 1; } var f = function(){ return 1; }
?
用typeof来验证f,返回"function",因此,函数是一种特殊的数据。同时,函数还可以像普通变量一样赋值给其他变量,甚至删除掉。
?
var sum = function(a, b) { return a + b; } var add = sum; delete sum; // true typeof sum; // "undefined" typeof add; // "function" add(1,2); // 3
在javascript中,function可以在不给予函数名的情况下使用。比如:
?
function(a){ return a; }
但是这样的函数并没有什么用处,要让他能被调用,可以有下面两种方法:
下面我们针对这两种方法来进行更细一些的了解。
?
由于函数可以像其他数据一样被赋给变量,能被定义、删除、复制,所以,同样的也可以被当做参数传递到另一个函数。
下面的例子是向函数中传入两个函数,执行以后返回两个函数返回值的和。
?
function invoke_and_add(a, b){ return a() + b(); }
?
然后定义两个简单的函数
?
function one() { return 1; } function two() { return 2; }
?
现在我们把这两个函数传入到invoke_and_add方法中。
?
invoke_and_add(one, two); // 3
?
执行以后,返回3。
另外,同样可以传入两个匿名函数来试试。
?
invoke_and_add(function(){return 1;}, function(){return 2;}); // 3
?
像这样类似的,传入一个函数A到另一个函数B中,在B中执行A,A就叫做回调函数。如果A是匿名函数的话,可以叫做匿名回调函数。
再看一个例子:
?
/** *把a,b,c 3个数乘以2以后,返回积的数组 */ function multiplyByTwo(a, b, c) { var i, ar = []; for(i = 0; i < 3; i++) { ar[i] = arguments[i] * 2; } return ar; } function addOne(a) { return a + 1; }
?测试:
?
multiplyByTwo(1, 2, 3); // [2, 4, 6] addOne(100); // 101
?
现在,我们需要传入3个数字,然后先对着3个数字乘以2,