1、Function对象
(1)js中一切都是对象
(2)函数名其实是引用函数定义对象的变量
(3)连function函数也是一个对象
2、arguments对象
(1)重载概念:
程序中可定义多个相同函数名,不同参数列表的函数
注意——
a.调用者不用区分每个函数的参数
b.执行时,程序根据传参参数的个数,四栋判断自动判断哪个函数执行
但是,js语法中没有“重载”,但可以采用arguments对象模拟重载效果
(2)arguments对象
函数对象内,自动创建专门接收所有参数值的类数组对象。
a.arguments[i]:获得传入的下标的对象
b.arguments.length:获得对象的长度
3、函数对象function
(1)函数声明3种方式
3-1:function 函数名 (参数) {
函数体;
return 返回值;
}
注意:函数名和函数定义都被提前
3-2:函数直接量
var 函数名 = function (参数) {
函数体;
return 返回值;
}
注意:仅函数名变量声明提前,函数定义留在本地,必须定义在调用前
var fun=function(){ console.log(1); } fun(); //1 var fun=function(){ console.log(2); } fun(); //2 var fun=3; fun(); //33-3:采用new关键字创建函数类型对象
函数名 = new Function("a","b",..,"函数体");
注意:new关键字创建函数类型对象,里边为“字符串”形式
拓展——面试题如下
/*以下函数正确的是*/ var arr=[1,12,23,45,24]; A.function compare(a,b){return a-b;} B.var compare = function(a,b){return a-b;} C.var compare = new Function(a,b,return a-b); arr.sort(compare); conosle.log(arr);
在上述题目中,C错误,A、B正确。
由于new关键字创建函数对象时,new关键字里边参数类型必须为“字符串”
所以,C选项为——“var compare = new Function("a","b","return a-b")”
(2)内存中的函数对象
创建函数对象时,同时创建2个对象
函数对象——函数的定义
作用域对象——保存了函数对象可用的变量位置(默认第一项指的是window对象,全局变量)
var a; //由于a只声明未赋值,所以为“undefined” function fun(a){ //定义函数时,同时创建2个对象——活动对象+ 作用域链对象(“仓库管理老板”) a++; console.log(a); } //这里的a为局部变量,作为一个“活动对象” a=100; //虽说没有var关键字,但是毕竟之前有a的定义,仍然为赋值 fun(a); //a++——>"101" 101 console.log(a); //100 a、调用函数时,又会创建1个新对象——活动对象,它是专门保存局部变量的对象在作用域链对象中追加指向活动对象的的引用
b、调用函数后,默认仅释放活动对象(保存的局部变量)
同时作用域链中活动对象的引用出栈
4、匿名函数
定义时,不指定函数名的函数。
何时使用?(2大用途)——自调、回调
(1)匿名函数自调:“定义完,立即执行,执行完立即释放”
a.何时使用:只有确定函数只执行一次时
b.如何自调匿名函数:
(function(参数){
...
})(参数值);
c.自调:定义在哪,就在哪执行,不提前
(2)匿名函数回调:向将函数作为对象传递给其他方法调用时,
由另一个函数自助决定在需要时调用
a.何时调用:只要将一个函数对象传递给其他方法调用
b.如何回调:直接将匿名函数的声明传入另一个函数中
5、闭包
问题:局部变量和全局变量的缺陷?
全局变量——容易产生“全局污染”
局部变量——无法共享,不能长久保存
既可以共享,长久保存,又不会全局污染——“闭包”
闭包作用:保护局部变量
缺陷:造成内存空间浪费
(1)判断闭包3特点:
a、嵌套函数
b、内层函数操作外层函数的局部变量
c、外层函数将内层函数返回到外部,且被全局变量保存
(2)判断闭包执行结果
a、外层函数被调用几次,就有几个受保护的局部变量副本
b、来自一个闭包的函数被调用几次,受保护的局部变量就变化几次
//外层函数被调用了几次,就有几个受保护的局部变量副本 function outer(){ var i=0; return i++; } var getNum1=outer(); //外层函数被调用1次,只有1个受保护对象副本i console.log(getNum1()); //0 console.log(getNum1()); //1 var getNum2=outer(); //外层函数被调用2次,就有2个受保护的i,互不干扰 console.log(getNum2()); //0