JavaScript知识点总结5

Function对象

js 中一切都是对象,函数也是对象,函数名其实就是引用函数定义对象的变量

1. arguments对象

重载:程序中可定义多个相同函数名,不同参数列表的函数;调用者不必区分每个函数的参数;执行时,程序根据传入的参数个数,自动判断选择哪个函数执行。

js 语法不支持重载!—> 可用arguments对象模拟重载效果。

arguments对象:函数对象内,自动创建的专门接受所有参数值的类数组对象。(类似于数组的对象)

        arguments[ i ]:获得传入的下标为 i 的参数值。

        arguments.length:获得传入的参数个数。

        专门在函数对象不写参数 或 不知道写几个参数时,用来接收所有参数。

        即使函数定义了参数变量,arguments对象同样会收到所有参数值。

//用arguments对象模拟重载
function calc( ){
    //如果用户传入一个参数
    if(arguments.length==1){
        alert(arguments[0]*arguments[0]);
    }
    //如果用户传入两个参数
    else if(arguments.length==2){
        alert(arguments[0] + arguments[1]);
    }
}

//调用函数calc()
calc(4);
calc(4,5);

2. 函数对象本质

(1)创建函数对象

//1.声明方式
//函数名和函数定义都被提前,在调用前后位置定义都行。
function 函数名(参数){
    函数体;
    return 返回值;
}

//2.函数直接量
//函数名变量的声明会提前,函数定义留在本地,必须定义在函数调用前。
var 函数名 = function(参数){
    函数体;
    return 返回值;
}

//3.使用new创建函数类型对象
var 函数名 = new Function("a","b",...,"函数体");  //a,b为参数;最后是函数体。

(2)内存中的函数对象

1.创建函数对象时:(同时创建2个对象)

       函数对象:函数的定义;

       作用域链对象(类似于栈):保存了函数对象可用的变量位置,默认第一项指向window对象(即一个函数可以使用window中的任何变量)。一个函数对象都会指向自己的作用域链对象。

2.调用函数时:(又会创建1个新对象)

        活动对象:专门保存(函数的)局部变量的对象

        在作用域链对象中追加指向活动对象的引用

3.调用后:(默认仅释放活动对象)

        作用域链中活动对象的引用出栈。

注:函数创建调用的过程见电脑本地图片(普通函数-有函数名的)!!

3. 匿名函数(节省内存空间)

定义时不指定函数名的函数。(注:匿名函数调用过程见本地图片-匿名函数!!)

何时使用:两大用途

(1)匿名函数自调:定义完,立刻执行;执行完,立刻释放。(一个对象没人调用它了,就会被垃圾回收机制收走。)

         自调:定义在哪,就在哪执行,不提前。

         何时使用:只有确定函数只执行一次时使用。

         如何自调:下面代码

/*
(function(参数){
    函数体;
})(参数值);
*/

<script>
//定义匿名函数:输出"页面开始加载"
(function(){
    alert("页面开始加载");
})();
</script>

<body>
    <h1>Welcome to Tj University</h1>
</body>

<script>
//定义匿名函数:输出"页面加载完成"
(function(){
    alert("页面加载完成");
})();
</script>

(2)匿名函数回调:在将函数作为对象传递给另一个函数,由另一个函数自主决定在需要时调用。

         何时使用:只要需要将一个函数对象作为参数传递给其他函数、方法调用时,就是用回调。

         如何回调:直接将匿名函数的声明传入另一个函数中。(如下,在sort方法中直接传入一个匿名函数)

arr.sort(function(a,b){returnn a-b;});

4. 闭包(作用:保护局部变量;缺点:占内存)

问题:全局变量 和 局部变量的缺陷

          全局变量:(谁都能用,谁都能改)—> 牵一发而动全身 —> 容易全局污染;

          局部变量:无法共享,不能长久保存(随函数的回收被回收)。

既可以共享、长久保存(全局能实现)+ 又不污染(局部可实现)——> 闭包

解决:三步(闭包的三个特点)

(1)定义外层函数,封装被保护的局部变量(对外层函数而言)(——>不被污染);

(2)定义内层函数:执行对外层函数的局部变量的操作(对内层函数而言,外层的局部变量—>全局的—>共享、保存)

(3)外层函数返回内层函数对象;并且外层函数被调用,结果被保存在另一个全局变量中。

何时使用:既要反复使用局部变量,又要避免全局污染,就用闭包。

//定义一个取号机函数
//每调用一次,顺序成成一个永不重复的序号
function outer(){
    var n=1;
    function inner(){
        return n++;
    }
    return inner;
}

var getNum = outer();
//getNum就是 --> function inner(){return n++;}

console.log(getNum());  //输出:1    因为getNum是个函数,所以可以加().
console.log(getNum());  //输出:2
console.log(getNum());  //输出:3

var n=100;  //全局污染,在没采用闭包的情况下,会形成干扰。

console.log(getNum());  //输出:4  不受上面一句的干扰。如果没采用闭包,就会受干扰。
console.log(getNum());  //输出:5

注:闭包原理图见电脑本地图片(闭包)!!!(其中图片里,只要有指进来的箭头的对象,就不能释放,没有只进来的箭头的对象才能释放。)

注:一个函数使用全局变量时,如果调用函数时无参数传递,则函数内操作改变的是全局变量;如果函数调用时有参数传递,则函数内部操作修改的是局部变量。

注:一个定义好的函数,如果在别处调用 或 传递时,

(1)只写一个函数名,代表指向函数对象变量;(给你一个榨汁机,自己榨汁)

(2)写函数名 + (),代表函数在此处立刻执行。(榨好的果汁)

判断闭包3特点(满足闭包的条件):

(1)嵌套函数;

(2)内层函数操作了外层函数的局部变量;

(3)外层函数将内层函数返回到外部,被全局变量保存住。

判断闭包执行结果:

(1)外层函数被调用几次(有几个类似getNum()函数),就有几个受保护的局部变量副本;

(2)来自一个闭包的函数被调用几次(即getNum()被调用几次),受保护的局部变量就变化几次;

笔试题:

function outer(){
    var arr=[];
    var i=0;
    for(;i<3;i++){
        arr.push(function(){retturn i})
    }
    return arr;
}
var getFuns = outer();
//外层函数只被调用一次,故只有一个受保护的i; i最后=3.
/*
getFuns-->[function(){retturn i},
           function(){retturn i},
           function(){retturn i}]
*/
console.log(getFuns[0]());  //因为i=3,且只有一个被保护的i,且i在内层函数中没有变化,故结果都为3.
console.log(getFuns[1]());  //3
console.log(getFuns[2]());  //3

砍断闭包的联系:内外层函数之间,加一层函数的调用,其中加一个参数变量 i 打断内外层函数中变量的联系。

function outer(){
    var arr=[]; 
    for(i=0;;i<3;i++){
        (function(i){
             arr.push(function(){retturn i})
        })(i);
    }
    return arr;
}
var getFuns = outer();
/*
getFuns-->[function(){retturn i},
           function(){retturn i},
           function(){retturn i}]
*/
console.log(getFuns[0]());  //0
console.log(getFuns[1]());  //1
console.log(getFuns[2]());  //2

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值