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函数的引用,只有函数名,没有后面的括号"()",这样函数才不会被调用.