函数是一段可以反复调用,可以接收参数并且根据参数的不同返回不同结果的代码块。
函数有三种定义方法:
1、function命令:
function f(a,b){
if(a>b){
return a;
}
}
2、函数表达式:
var f = function(a,b){
if(a>b){
retuen a;
}
};
3、Function 构造函数:
var f = new Function(
'x',
'y',
'return x+y'
);
//等价于:
var f = function(x,y){
return x+y;
};
上面三种定义函数的方式常用的是1和2,第三种由于不直观基本没用。
对于第2种定义方式也可以如下定义:
var f = function f1(a,b){
if(a>b){
return a;
}
};
其中函数名f1只能在函数内部调用,其他地方不能用。这样定义的好处有两个:
(1)可以在函数内部调用自身
(2)方便除错(除错工具在显示函数时可以直接显示函数名而不是显示一个匿名函数)
上面讲了函数的定义方式,下面说说函数自带的一些属性和方法:
name属性:name属性返回一个函数的名字:
function f(a,b){
}
console.log(f.name);//返回f
对于用函数表达式定义的函数name属性返回的函数名有两种情况:
(1)匿名函数
var f = function(a,b){};
console.log(f.name);//返回f
(2)表达式中加函数名
var f = function f1(a,b){};
console.log(f.name);//返回f1
name属性的一个用处是:在函数的参数也是函数时,可以使用name属性知道传入的函数的名称
length属性:length属性返回函数定义时的参数个数,注意是定义时的参数个数,并不是调用时传入的参数个数。
function f(a,b,c){}
console.log(f.length);//3
var f1 = function f2(a,b,c.d){};
console.log(f1.length);//4
arguments :arguments 可以获取调用函数的传入的参数,arguments 在函数内部调用,看着像数组但arguments 并不是一个数组。arguments[0]表示传入的第一个参数,arguments[1]表示传入的第二个参数,以此类推。
function f(a,b,c){
console.log(arguments[0]);
console.log(arguments[1]);
console.log(arguments[2]);
}
var f1 = f(1,2,3);
f1;//依此输入1,2,3
根据前面章节讲的函数名的提升,在后面定义的同名函数会覆盖前面定义的函数,覆盖后前面定义的函数就一直失去了作用。
闭包:
闭包是JavaScript中的一个特色,要了解闭包首先需要了解作用域,这个前面的章节已经讲过,定义在函数内部的局部变量在函数外面是不能访问的,如果我们想得到定义在函数内部的局部变量该怎么操作呢?闭包就是用来解决这个问题的。
function f(){
var n = 0;
function f1(){
console.log(n);
}
}
通过对作用域的了解,上面函数中f1定义在函数f内部,是f的子函数,所以f1可以获取到函数f中定义的变量,那么当函数f外面想获取函数f内部的变量时我们直接return函数f1就可以解决:
function f(){
var n = 0;
function f1(){
return n;
}
return f1();
}
var f2 = f();
console.log(f2);
函数f的内部函数f1直接返回函数f中定义的变量n,而函数f的返回值又是函数f1,那么当在函数f外部通过调用函数f就可以获取f中的局部变量n。
闭包其实就是函数中的函数,而且因为全局变量是一直存在于内存中的,当外部变量通过闭包获取函数中的局部变量时 会造成函数中的局部变量也一直存在于内存中 不能被垃圾回收机制回收。
function f(a) {
return function () {
console.log(a);
return a += 1;
}
}
var f2 = f(1);
f2();//1
f2();//2
f2();//3
从上面的例子可以看出:闭包延长了局部变量的生命周期。
闭包还有一个作用就是封装对象的私有属性和私有方法:
function person(){
var _age;
var _name;
function setAge(a){
_age = a;
}
function getAge(){
return _age;
}
function setName(n){
_name = n;
}
function getName(){
return _name;
}
return{
setName:setName,
getName:getName,
setAge:setAge,
getAge:getAge
}
}
var p = person();
p.setName("LT");
p.setAge(25);
console.log("name"+p.getName());//输出LT
console.log("age:"+p.getAge());//输出25
闭包的使用会延长局部变量的生命周期,不能滥用闭包否则会造成浏览器的性能下降。