JavaScript的进阶之路(六)理解函数

函数:定义一次,多次调用;用于对象的属性则称为对象的方法;在JavaScript中,函数即对象;嵌套的函数形成闭包;

定义函数和简单调用函数:

            //函数定义
            function f1(){ //没有参数的函数
                return true;
            }
            function f2(x,y){//有参数的函数
                return x+y;
            }
            var f3=new Function("x","y","return x+y"); //new方法定义函数
            var f4 = function(x,y){return x+y;}  //表达式定义函数
            var f5 = function fac(x){if(x<=1) return 1;return x*fac(x-1);} //表达式定义一个有名字的函数f5,递归调用函数
            
            //函数的用法
            console.log(f5(5)); //直接调用
            var f6 = (function(x){return x*x;})(10);  //定义后立即调用执行,此时f6是number 100
            var data = [1,3,2,5,4];
            var sort = data.sort(function(a,b){return a-b;});  //函数作为值传递给其他函数
            function f7(x,y){                
                function square(a){ return a*a};
                return square(x)+square(y);   //内部函数square可以直接访问外部函数f7的参数x,y
            }
        
            console.log(f7(2,3));

函数的形参和实参

            //实例:给数组中添加元素
            function addElement(e,a){
                a = a || [];  //注意这句 : 未定义则为空数组,这样在调用函数的时候第二个参数可以不传
                a.push(e);
                return a;
            }
            var arr = [1,2,3];
            console.log(addElement(4));
            console.log(addElement(4,arr));
            //arguments参数数组
            var factorial = function (x){
                if(x<=1) return 1;
                return x*arguments.callee(x-1);    //arguments.callee递归的调用自身
            }

作为值得函数:将函数赋值给变量,赋值给对象的属性,作为其他函数的参数,都是函数作为值得表现。

函数作用域:在函数中声明的变量,在函数体内都是可见的(包括嵌套函数内),在函数外部是不可见的,要想在函数外部访问,需要用到闭包;

 

关于闭包:

理解闭包:闭包是一种特性:通过作用域链,函数体内部的变量都可以保存在函数作用域内。这个变量作用域是在函数定义时就决定的。

但是:调用时的变量作用域和定义函数时的变量作用域不一样的时候呢?答案是:总是返回定义函数时的变量作用域。

闭包的用途:

1、访问函数作用域内的变量

            //嵌套函数的词法作用域规则
            var str="global";
            function check(){
                var str="local";
                function f(){return str};
                return f();  
            }
            console.log(check()); //local
            
            var str1="global";
            function check1(){
                var str1="local";
                function f(){return str1};
                return f;
            }    
            //这里看似调用潜逃的函数f()  在函数作用域外没有这个函数,但是同样返回local;因为变量作用域链在函数定义的时候就创建了
            console.log(check1()());    //local

2、防止变量污染

            var count = 1;  //这里的变量可以影响函数体common的结果
            function common(){
                return count++;
            }
            common();
            console.log(count);  // 2 
            
            var a = 3;  //这里变量a可以随意定义,不会污染影响now函数体内的变量
            //定义一个函数并立即调用
            var now=(function f(){
                var a=1;
                return function(){
                    return ++a;
                }
            })();
            console.log(now());

函数的属性、方法

            //函数的属性、方法和构造函数
            //属性length和prototype


function f(x,y,z){ return x+y+z; } console.log(f.call(this,1,3,4)); //8 console.log(f.apply(this,[1,2,3])); //6 var array=[1,2,3,4,5]; var max=Math.max.apply(this,array); var max1=Math.max(1,2,3,4,5); var max2=Math.max.call(this,1,2,3,4,5); console.log(max+" "+max1+" "+max2); / 5 5 5 //bind()方法 给对象绑定一个自定义的函数 var o={x:1}; //待绑定的对象 function fn(y){return this.x+y};//待绑定的函数 var g= fn.bind(o); console.log(g(2)); // 3 function obf(f,o){ if(f.bind){ return f.bind(o); }else{ return function(){ return f.apply(o,arguments); } } } var g1=obf(fn,o); console.log(g1(2)); //3 var sum=function(x,y){return x+y}; var sum1=sum.bind(null,1); console.log(sum1(2)); // 3 var sum2=function(y,z){return this.x+y+z}; var sum3=sum2.bind({x:1},2); //绑定this和y console.log(sum3(3));
posted @ 2018-02-05 12:01  魔兽IT  阅读(151)  评论(0编辑  收藏  举报