• js 函数


    一、函数的定义

    window.onload=function(){
            //函数的调用
            fcName();
            fc1();
            var num=fc2(10,20);
            fc3();
            fc4();
        }
        //函数的参数列表 相当于函数入口;return 相当于函数出口
        /*1.function 语句式
          特点:a.创建一次存储在内存中,每次使用从内存中取,效率高
                b.js 解析器会优先解析然后存储在内存中,使用时直接取内存中的(优先解析)
                c.具有函数作用域
        */
        function fcName(){
           alert("function 语句式");
        }
        /*2、函数的直接量式(ECMAScript推荐)
          特点:a.创建一次存储在内存中,每次使用从内存中取,效率高
                b.js 解析器 只是声明了变量fc1 并没有给其赋值 ,只用当程序运行到这里时才会赋值(顺序解析)
                c.具有函数作用域
        */
        var fc1=function(){
            alert("函数的直接量式");
        } 
        /*
          3.Function 构造函数式
          特点:a.每次创建使用后就会销毁 不占用内存但每次使用都要创建 所以效率低
                b.js 解析器 只是声明了变量fc2 并没有给其赋值 ,只用当程序运行到这里时才会赋值(顺序解析)
                c.顶级作用域
        */
        var fc2=new Function("a","b","return a+b;");
        var fc3=new Function("alert('构造函数式')");
        //三种函数的作用域
        var m=0;
        function fc4(){
            var m=1;
            function fc5(){
                alert(m);// 1
            };
            var fc6=function(){
                alert(m);// 1
            }
           var fc3=new Function("return m;");
           fc5();
           fc6();
           alert(fc3());// 0
        }

    二、函数的参数

    <script type="text/javascript">
        window.onload=function(){
            fc1(10,20);
        }
        /*
          在js中形参个数可以与实参个数不同
        */
        function fc1(a,b,c){
            var length=fc1.length;//获得形参个数 (不建议使用)
            /*
             arguments 的对象可以访问函数的实际参数(只能在函数内部使用)
            */
            var length2=arguments.callee.length;//获得形参个数(arguments.callee 指向函数本身)
            var args=arguments.length;//实际参数的个数
            var arg1=arguments[0];//获得第一个实际参数
            //在实际开发中我们会先判断参数个数是否相同再执行代码
            if(arguments.callee.length===arguments.length){
               return a+b+c;
            }else{
                return '参数不正确';
            }
        }
        </script>

    三、this 关键字

        window.onload=function(){
            //this 对象是指在运行时基于执行环境所绑定的;this总是指向调用者
        }
        var k=10;
        function test(){
            this.k=20;
        }
        alert(k);// 结果为10;
        test();// 相当于window.test();
        alert(k); // 结果为 20  因为 调用 test()函数的是window对象 所以this指向window对象 this.k 覆盖了 var k;

    四、call、apply关键字

    window.onload=function(){
            // call 、apply 作用一:用于绑定一些函数 用于传递参数、调用
            alert(call1(10,20));//30
            alert(apply1(20,30));// 50
        }
        function sum(x,y){
            return x+y;
        }
        /*
          把 sum函数绑定到this(call1()函数)上
        */
        function call1(x1,y1){
            return sum.call(this,x1,y1);
        }
        function apply1(x2,y2){
            return sum.apply(this,[x2,y2]);
        }
    window.onload=function(){
            // call 、apply 作用二:用于扩充作用域
            window.color="red";
            var obj={color:"blue"};
            alert(showColor.call(this));//red 因为this指代调用者window 所以showColor 被绑定在window上
            alert(showColor.call(obj));// blue showColor 被绑定在obj上
        }
        function showColor(){
            return this.color;
        }
    window.onload=function(){
            // 模拟 call 、apply 方法的实现方式
            var obj=new Obj(10,30);
            obj.method=test;
            alert(obj.method(obj.x,obj.y));
            delete obj.method;//使用后及时删除 临时调用
        }
        function test(a,b){
            return a*b;
        }
        //自定义的对象
        function Obj(x,y){
            this.x=x;
            this.y=y;
            return x*y;
        }

    五、执行环境、作用域链

        执行环境:      在javascript里面执行环境分为两类,一类是全局环境,一类是局部环境,整个页面里被共享的方法和属性就是在全局环境,

                         相对于全局环境,函数{}号里的执行环境就是局部环境,执行环境定义了变量或函数有权访问的其他数据,决定了它们各自的行为,

                         每个执行环境都定义了一个与之相关的变量对象,环境中定义的所有变量和函数都保存在这个对象里,虽然我们自己编写的代码无法访问这个对象,

                        但解析器在处理数据时候后台会使用到它。
                               全局执行环境另一种说法是最外围的一个执行环境,在web浏览器的范围中(actionscript也是施行了ECMAScript标准,

                        它的全局范围就和javascript的全局范围不同),全局执行环境被认为是window对象,因此全局变量和函数都是作为window对象的方法和属性来创建的,

                       全局执行环境知道应用程序退出比如关闭网页或浏览器才会被销毁。而局部环境则是以函数对象作为关联对象。

    作用域链:    Javascript高级程序设计(第三版)(P73):当代码在一个环境中执行时,会创建变量对象的的一个作用域链(scope chain)。

                       作用域链的用途,是保证对执行环境有权访问的所有变量和函数的有序访问。作用域链的前端,始终都是当前执行的代码所在环境的变量对象

                        。如果这个环境是一个函数,则将其活动对象作为变量对象。

                       每一个函数都有自己的执行环境,当执行流进一个函数时,函数环境就会被推入一个环境栈中,而在函数执行之后,栈将其环境弹出,

                       把控制权返回给之前的执行环境,这个栈也就是作用域链。

    自我理解作用域链是由于js的变量都是对象的属性,而该对象可能又是其它对象的属性,而所有的对象都是window对象的属性,

                   所以这些对象的关系可以看作是一条链

     

     //1、最外层执行环境 window对象
         var color1="blue";
         function changeColor(){//每个函数 都是一个执行环境
             var color2="red";
             function swapColor(){//该函数 也会产生一个执行环境(variable obj)
                 //该函数内部可以访问 color1 ,color2 
                 var color3=color2;
                 color2=color1;
                 color1=color3;
             }
             //这里可以访问color1、color2 但无法访问 color3
             swapColor();
         }
         //这里只能访问 color1
         changeColor();
         //环境变量 可以一层一层的向上进行追溯 可以访问它的上级环境变量和函数

     

    六、垃圾收集、块级作用域

     //垃圾回收机制 一.标记法 
          function test1(){
                  var a=10;
                  var b=20;
          }
          /*
            当执行test()函数时变量a、b 会被标记为被使用,一段时间间隔后会标记为未使用
            这是js的垃圾回收机制会回收a、b
          */
          test();
         //垃圾回收机制二:计数法
         function test2(){
             var a=10;// 被计数 count++  count=1;
             var c;
             c=a; //count++  count=2;
             a=50;// count-- count=1;
         }
         //当count=0 时js的垃圾回收机制就会回收 该变量

    块级作用域

    /*
            在高级程序预言中 for if 语句具备块级作用域的概念
            在js中没有块级作用域的概念 所以会打印 6
        */
            function test1(){
                for(var i=0;i<5;i++){
                    alert(i);
                }
                alert(i);// 6
            }
          // 模拟js的块级作用域 使用()
              function test2(){
                (function (){
                    for(var i=0;i<5;i++){
                    alert(i);
                }
                })();    
                alert(i);// 这样 i在 for循环结束后 就会被 回收 所以程序出错
            }

    七、closure 闭包

    <script type="text/javascript">
            var name="AA";
            var obj={
                name:"BB",
                getName:function(){
                    return function(){
                        return this.name;
                    }
                }
            };
            var fg=obj.getName()();//AA
            //拆开写
            var m=obj.getName();//getName()函数 返回的是一个匿名函数 我们定义我为函数m()
            /*
                很显然m()属于window对象 根据作用域链的特点变量只能向上层层追溯
                 所以 this.name指向的是window.name, 因此最终打印AA
            */
            var ff=m();//AA
    
            //如果我希望最终的结果是 BB 该如何改造代码
            var obj1={
                name:"BB",
                getName:function(){
                    var o=this;//this 指向obj1 
                    return function(){
                        return o.name;
                    }
                }
            };
            var m1=obj1.getName();
            var dd=m1();//虽然m1()函数属于window对象但 它内部的name属性属于obj1对象 所以结果是BB
    
         /*
            闭包:一个函数可以访问另外一个函数作用域中的变量
            封闭性:起到保护变量的作用
         */
         function f(x){
             var temp=x;
             return function(x){
                 temp+=x;//temp又被使用 所以在2级作用域后没有被回收
                 return temp;
             }
         }
         var te1=f(20);
         var te=te1(2);//22
             te=te1(3);//25
             te=te1(5);//30
        </script>
  • 相关阅读:
    要养成记录技术问题的习惯
    js排序方法
    阶乘算法练习
    简易的自定义滚动条加鼠标滑轮事件结合使用
    等虚线框的拖拽
    照片墙效果
    苹果导航菜单效果
    简易封装js库
    JQ 实现切换效果
    三级菜单
  • 原文地址:https://www.cnblogs.com/jalja/p/4865170.html
Copyright © 2020-2023  润新知