闭包、作用域链、函数

闭包

概念:闭包就是能够读取其他函数内部变量的函数。

作用:一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。

 

闭包注意问题:

由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。

闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。

 

作用域链

概念:在一个函数中嵌套多个函数,并且各自定义的相同的变量名,当函数访问变量时,就形成了作用域链。

查找顺序:从当前函数开始查找,如果没有找到,向上一级函数开始查找,直到找到为止,如果一直没有找到,则说明该变量未定义。

作用域链明确表示:在变量解析过程中首先查找局部作用域,然后查找上层作用域。

 

垃圾回收

 

有两种策略来实现垃圾回收:

标记清除引用计数

标记清除:垃圾收集器在运行的时候会给存储在内存中的所有变量都加上标记,然后,它会去掉环境中的变量的标记和被环境中的变量引用的变量的标记,此后,如果变量再被标记则表示此变量准备被删除。 2008年为止,IE,Firefox,opera,chrome,Safari的javascript都用使用了该方式;

引用计数:跟踪记录每个值被引用的次数,当声明一个变量并将一个引用类型的值赋给该变量时,这个值的引用次数就是1,如果这个值再被赋值给另一个变量,则引用次数加1。相反,如果一个变量脱离了该值的引用,则该值引用次数减1,当次数为0时,就会等待垃圾收集器的回收。

 

函数嵌套

一个函数定义的内部可以定义其他的函数。

 

函数自执行

(function (argument1,argument2){

  这里是要执行的代码

})();

将函数声明用()括起来,相当于一个函数表达式。

 

创建\调用函数注意问题

如果两个函数的命名相同,后面的将会覆盖前面的函数。 以基本语法声明的函数,会在页面载入的时候提前解析到内存中,以便调用。所以可以在函数的前面调用。但是以字面量形式命名的函数,会在执行到他的时候,才进行赋值。所以只能在函数的后面调用。

在不同的<script></script>块中,因为浏览器解析的时候是分块解析的,所以前面的块不能调用后面块的函数,所以在不同的块之间调用函数的时候,应该先定义后调用。

 

带有参数的函数

 

参数的作用:

可以动态的改变函数体内对应的变量的值,使同一函数体得到不同的结果。

形参:在定义函数的时候,函数括号中定义的变量叫做形参。用来接受实参的。

实参:调用函数的时候,在括号中传入的变量或值叫做实参。用于传递给形参。

 

参数详解

参数的类型

  – 可以是任何的数据类型。

参数的个数

  – 实参和形参数量相等,一一对应。

  – 实参小于形参,不会报错,多出形参的值会自动赋值为undefined。

  – 实参大于形参,不会报错,但如果要获得多出实参的值,需要用arguments对象来获取。

 

arguments对象详解

 

每创建一个函数,该函数就会隐式创建一个arguments对象,他包含有实际传入参数的信息。

arguments对象的属性

length 获得实参的个数

callee 获得函数本身的引用

– 访问传入参数的具体的值。arguments[下标]

 

Var a =100
 function test() {    
     alert(a);    
     a = 10;    
    alert(a);    
     }    
 test();    
 alert(a);    阅读以上代码,结果应为多少?

 

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title></title>
    </head>
    <body>
        <script>
        //概念:闭包就是能够读取其他函数内部变量的函数。
        //闭包可以让局部变量持久化
        
        //作用:一个是前面提到的可以读取函数内部的变量,
             //另一个就是让这些变量的值始终保持在内存中
        
        //【注意】1、在退出函数之前,将不使用的局部变量全部删除
                //2、闭包会在父函数外部,改变父函数内部变量的值。
                //3、不要随便改变父函数内部变量的值
                //4、函数在调用时会开辟新空间,这块内存空间在函数执行完毕时释放
        //createComparisonFunction() 作用域
        
            function createComparisonFunction(propertyName){
                return function(object1,object2){
                    
                    //内部函数 访问了propertyName
                    var value1 = object1(propertyName);
                    var value2 = object2(propertyName);
                    
                    if(value1 < value2){
                        return -1;
                    }else if(value1 > value2){
                        return 1;
                    }else{
                        return 0;
                    }
                };
            }

            function compare(value1,value2){
                if(value1 < value2){
                        return -1;
                    }else if(value1 > value2){
                        return 1;
                    }else{
                        return 0;
                    }
            }
            var result = compare(5,10);
        </script>
    </body>
</html>

用闭包打印li的下标

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <ul>
            <li>蜡笔小新</li>
            <li>野原葵</li>
            <li>野原美伢</li>
            <li>野原广志</li>
        </ul>
        <script>
//            var li = document.getElementsByClassName("li");
//            for(var i = 0;i<li.length;i ++){
//                function dianji(){
//                    var j = i;
//                    function a(){
//                        alert("下标为"+j);
//                    }
//                    return a;
//                }
//                li[i].onclick = dianji()
//            }
            
            //第二种方法
            var li = document.getElementsByTagName("li");
            for(var i = 0;i<li.length;i ++){
                li[i].onclick = function(num){
                    return function(){
                        alert(num);
                    }
                }(i);//执行匿名函数
            }
                
        </script>
    </body>
</html>

 

posted @ 2017-06-25 21:24  谁是李慧  阅读(439)  评论(0编辑  收藏  举报