this的值:在函數執行時,this關鍵字並不會指向正在運行的函數自己,而是指向調用該函數的對象.因此,若是你想在函數內部獲取函數自身的引用,只能使用函數名或者使用argument.callee屬性(嚴格模式下不可用),若是該函數是一個匿名函數,則你只能使用後者. node
三種方式: 算法
1)函數聲明 (function語句) 數組
function name([param[, param[, ... param]]]) { statements }name函數名.
param函數的參數的名稱,一個函數最多能夠有255個參數. 閉包
statements這些語句組成了函數的函數體. ide
2)函數表達式 (function操做符) 函數
函數表達式和函數聲明很是相似,它們甚至有相同的語法 (查看function操做符瞭解詳情 ): 優化
function [name]([param] [, param] [..., param]) { statements }name函數名,能夠省略,省略函數名的話,該函數就成爲了匿名函數.
param函數的參數的名稱,一個函數最多能夠有255個參數. this
statements這些語句組成了函數的函數體. spa
3)Function構造函數 prototype
和其餘類型的對象同樣,Function對象也可使用new操做符來建立:
new Function (arg1, arg2, ... argN, functionBody)arg1, arg2, ... arg N一個或多個變量名稱,來做爲函數的形參名.類型爲字符串,值必須爲一個合法的JavaScript標識符,例如Function("x", "y","alert(x+y)"),或者逗號鏈接的多個標識符,例如Function("x,y","alert(x+y)")
functionBody一個字符串,包含了組成函數的函數體的一條或多條語句.
即便不使用new操做符,直接調用Function函數,效果也是同樣的,仍然能夠正常建立一個函數.
在函數內部,你可使用arguments對象獲取到該函數的全部傳入參數. 查看 arguments.
arguments 對象是函數內部的本地變量;arguments 已經再也不是函數的屬性了。
你能夠在函數內部經過使用 arguments 對象來獲取函數的全部參數。這個對象爲傳遞給函數的每一個參數創建一個條目,條目的索引號從 0 開始。例如,若是一個函數有三個參數,你能夠經過如下方式獲取參數:
arguments[0] arguments[1] arguments[2]
參數也能夠被從新賦值:
arguments[1] = 'new value';
arguments對象並非一個真正的數組。它相似於數組,但沒有數組所特有的屬性和方法,除了 length。例如,它沒有 pop 方法。不過能夠將其轉換成數組:
var args = Array.prototype.slice.call(arguments);注:不該在 arguments 對象上使用 slice 方法,這會阻礙 JavaScript 引擎的優化 (好比 V8 引擎)。做爲替代,應經過遍歷 arguments 對象的方式來構建一個新的數組。
arguments 對象僅在函數內部有效,在函數外部調用 arguments 對象會出現一個錯誤。
若是你調用一個函數,當這個函數的參數數量比它顯式聲明的參數數量更多的時候,你就可使用 arguments對象。這個技術對於參數數量是一個可變量的函數來講比較有用。 你能夠用 arguments.length來獲得參數的數量,而後能夠用 argumentsobject 來對每一個參數進行處理。 (想要獲得當一個函數定義時的該函數的參數數量, 請使用 Function.length屬性。)
function myConcat(separator) { var args = Array.prototype.slice.call(arguments, 1); return args.join(separator); }
// returns "red, orange, blue" myConcat(", ", "red", "orange", "blue"); // returns "elephant; giraffe; lion; cheetah" myConcat("; ", "elephant", "giraffe", "lion", "cheetah");
一個函數能夠指向並調用自身。 有三種方法可使一個函數指向自身:
例如, 考慮下面的函數定義:
var foo = function bar() { // statements go here };
在函數體內, 下列語句是等價的:
function walkTree(node) { if (node == null) // return; // do something with node for (var i = 0; i < node.childNodes.length; i++) { walkTree(node.childNodes[i]); } }將每一個遞歸算法轉化爲非遞歸的都是可能的,但一般邏輯會變得十分複雜,而且這樣作須要用到棧。事實上,遞歸自己用到了棧:函數棧。(每次感受都迷糊在這個棧裏面
function foo(i) { if (i < 0) return; document.writeln('begin:' + i); foo(i - 1); document.writeln('end:' + i); } foo(3);
begin:3 begin:2 begin:1 begin:0 end:0 end:1 end:2 end:3
你能夠將一個函數嵌套在另外一個函數內部.被嵌套的函數 (內部函數)是隻屬於嵌套它的函數(外部函數)的私有函數.這樣就造成了一個閉包.
function addSquares(a,b) { function square(x) { return x * x; } return square(a) + square(b); } a = addSquares(2,3); // returns 13 b = addSquares(3,4); // returns 25 c = addSquares(4,5); // returns 41因爲內部函數造成了一個閉包,你能夠把這個內部函數當作返回值返回,該函數引用到了外部函數和內部函數的兩個參數:
function outside(x) { function inside(y) { return x + y; } return inside; } fn_inside = outside(3); result = fn_inside(5); // returns 8 result1 = outside(3)(5); // returns 8
arguments: 一個"類數組"的對象,包含了傳入當前函數的全部實參.
arguments.callee : 指向當前正在執行的函數.
arguments.caller : 指向調用當前正在執行的函數的函數,請使用arguments.callee.caller代替
arguments.length: 傳入當前函數的實參個數.
arguments.callee.length:形參的個數例子:檢測一個函數是否存在
你可使用typeof操做符來檢測一個函數是否存在.下例中,首先檢測window對象的noFunc屬性是不是一個函數,若是是,則調用它,不然,進行其餘的一些動做.
if ('function' == typeof window.noFunc) { // 調用 noFunc() } else { // 進行其餘動做 }
注意在if語句中,使用的是對noFunc函數的引用,只有函數名,沒有後面的括號"()",這樣函數纔不會被調用.