所谓过程式编程(或函数式编程),最重要的语法就是函数,js虽然号称OOP语言,但实际上函式编程是更为经常使用且你们熟悉的编程方式。这里就几个重要概念进行说明。编程
总结来讲,函数是js语言的第一类对象,能够被调用、赋值、传递....数组
函数定义安全
function 函数名(参数1,参数2,参数3...){闭包
函数体语句app
renturn 返回值;函数式编程
}函数
说明:this
一、函数体return关键字指定返回值,由于是弱对象语言,所以不须要在定义中指定函数返回值,也能够没有return语句,返回值是undefined;spa
二、参数不用指定类型,若是类型很重要,须要使用typeof方法进行检测。参数个数可变,且调用时个数能够不和参数个数匹配。prototype
在函数内定义函数,叫嵌套函数。
用函数直接量定义函数,函数直接量是表达式,能够定义匿名函数。
function f(x){ return x*x;} var f = function(x){ return x*x;}; //第一行是常规定义方式,第二行匿名函数量的方式定义函数。
虽然直接量匿名定义函数,也能够对函数命名,这在递归编程中很是有用。
var f = function fact(x){ if (x<-1) return 1; else return x*fact(x-1); };
函数参数
函数能够以任意数目的参数来调用,而无论函数定义中参数多少,向任何函数传递任意类型的参数都是合法的。
一、可选参数
当调用函数时,参数少于申明的参数个数的时候,其余参数的值是undefined。所以但愿编写某些参数可选的安全的函数,方法是为可以忽略的参数分配一个合理的默认值。但参数的顺序是必须的,所以可选参数应放在最后。
function copyPropertyNamesToArray(o,/* optional */ a){ if(!a) a=[]; //若是undefined 或者 null,使用空数组 for(var property in o ) a.push(property); return a; } var a = copyPropertyNamesToArray(o); //不使用可选的参数a copyPropertyNamesToArray(p,a); //使用两个参数
二、Arguments对象
在函数体内,能够用arguments标示符引用auguments对象,arguments对象是一个相似数组的对象,可按照数目获取传递给函数的参数值,并定义了callee属性。
arguments.length属性返回参数个数,arguments[0]返回第一个参数的值,使用数组下标方式获取参数值。
属性callee用来引用当前正在执行的函数,可用来对未命名的函数递归调用自身。
function(x){ if(x<=1) return 1; return x*arguments.callee(x-1); }
如何不用记住参数顺序调用参数?
前面讲到,调用函数参数个数虽然不限,但参数顺序是必须保证的,这比较麻烦。让参数以键名/值对的方式传递参数,是一个好办法。实现方法是定义一个对象,用对象属性名/值做为函数参数。
function arrayCopy(/*array*/ from,/*index*/from_start,/*array*/ to,/*index*/to_start,/*integer*/ length) { // 方法代码,数组from从from_start位置开始复制长度为length的数据到到数组to从to_start位置开始,长度为length; } function easyCopy(args){ arrayCopy(args.from, args.from_start||0, args.to, args.to_start||0, args.length); } var a=[1,2,3,4]; var b=new Array(4); easyCopy({from:a,to:b,length:4});
函数能够做为数据赋值给变量。
function square(x) { return x*x;} var a=square(4); //a=16 var b=square; //b引用到square var c=b(5); //c=25
函数能够复制给对象的属性,称为方法。方法其实不过是存储在对象属性中的而且经过对象来调用的函数,不过和一般函数不一样的是,对象会默认给方法赋值一个对象实例,标示符是this。
var o=new Object; o.square=function(x){ return x*x;} y=o.square(16);
还能够复制给数组元素。
var a=new Array(3); a[0]=function(x){ return x*x; } a[1]=20; a[2]=a[0](a[1]); //a[2]=400
函数还能够做为参数传递给其余函数。
函数的属性和方法
函数是js对象的一种特殊类型,也具备属性和方法。
length属性:只读属性,返回参数个数;
prototype属性:预约义的原型对象;
函数自定义属性:能够在函数内部定义变量做为函数的属性;
apply()和call()方法:该方法能够像调用其余对象的方法同样调用函数。第一个参数是要调用的函数的值,在函数体内这个参数是关键字this,剩余参数是要传递给要调用的函数的值。
f.call(o,1,2); 等同于: o.m=f; o.m(1,2); delete o.m;
函数做用域和闭包
调用对象
当js解释器调用一个函数,它首先将做用域设置为定义函数的时候起做用的那个做用域链。接下来,在做用域链前面添加一个新的对象,叫作调用对象。调用对象用arguments属性调用函数的Arguments对象,函数的命名的参数和var语句的局部变量添加到调用对象的后面。
闭包
子函数可使用父函数中的局部变量,这种行为就叫作闭包!按照js做用域链原理,嵌入函数老是可以访问外部函数的全部参数和变量。所以,全部函数都是闭包的,嵌入函数可做为闭包使用。