犀牛书学习笔记(3):函数

所谓过程式编程(或函数式编程),最重要的语法就是函数,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做用域链原理,嵌入函数老是可以访问外部函数的全部参数和变量。所以,全部函数都是闭包的,嵌入函数可做为闭包使用。

相关文章
相关标签/搜索