函数(定义、参数、return、变量、作用域、预解析)

孤者浪人 提交于 2021-02-11 13:26:11

一、函数定义

1.方式一       function 函数名(参数){  函数体  }——————函数声明的方法

function fn(a){
            console.log(a);
        };

2.方式二      var  变量名  =  function(参数){  函数体  }——————函数表达式

var fn=function(a){
            console.log(a);
        };

3.注意的问题:

  • 函数必须先定义,再调用
//先声明
        function fn(a){
            console.log(a);
        }
        //调用函数
        fn(1);
  • 函数最好一个功能一个函数
  • 函数推荐使用驼峰式命名
function getMax(a,b){
            if(a<b){
                console.log(b);
            }else{
                console.log(a);
            }
        };
        getMax(2,3);//3
  • 有名字的函数称为命名函数;反之,没有名字的函数称为匿名函数
  • 方式二定义的函数称为函数表达式,把一个函数给一个变量,调用函数用   变量名(参数)
  • 函数表达式声明的函数后面要加分号
  • 区别:函数声明的方法重名会覆盖,函数表达式相当于变量的再赋值
function f1(){
            console.log("我是第一个函数");
        };
        function f1(){
            console.log("我是第二个函数,我覆盖了第一个函数")
        };
        f1();//我是第二个函数,我覆盖了第一个函数
var f2=function(){
            console.log("我是第一个函数")
        };
        f2=function(){
            console.log("我是第二个函数") 
        };
        f2();//我是第二个函数
  • 函数的自调用,没有名字,调用------声明的同时,一次性的
fn=function(){
            console.log("函数fn代表整个函数代码,后面加括号就是调用");
        }();//会输出内容,相当于fn()的调用,简写版

二、参数

1.形参:函数定义的时候,小括号里面的变量

2.实参:函数再调用的时候,小括号里面的变量或者值

//声明定义函数的时候,a和b就是形参
        function getMax(a,b){
            if(a<b){
                console.log(b);
            }else{
                console.log(a);
            }
        }
//调用函数的时候,传入的值,2和3就是实参
        getMax(2,3);//3

3.形参个数和实参个数可以不一致

function getMax(a,b,c){
            if(a<b){
                console.log(b);
            }else{
                console.log(a);
            }
        }
        getMax(2);//当传入的是一个值得时候,输出就是第一个参数a的值2
        getMax(2,3);//形参多于实参,输出依然是3
        getMax(2,3,4,5);//实参多于形参,输出也是3

三、return返回

1.return后面有内容,这个内容被返回了

function getSum(a,b){
            return a+b;
        };
        console.log(getSum(2,3));//5

2.类型:有参数有返回值/没有返回值,没有参数有返回值/没有返回值

常用:

//有参数有返回值
        function getSum(a,b){
            return a+b;
        };
        console.log(getSum(3,4))//7
        //有参数没有返回值
        function sayHi(a){
            console.log("这是我输入的语句:"+ a +"!")
        };
        sayHi("今天天气真好");//这是我输入的语句:今天天气真好!

3.函数没有返回值,但是接收了,结果是undefined

function getSum(a,b){
            var c=a+b;
        }
        console.log(getSum(2,4));//undefined

4.没有明确的返回值,即return后面没有内容,结果也是undefined

function getSum(a,b){
            var c=a+b;
            return;
        }
        console.log(getSum(2,4));//undefined

5.return后面的代码不会执行

function getSum(a,b){
            var c=a+b;
            return c;
            console.log("我在return的后面,不会执行了");
        };
        console.log(getSum(2,4));//6

6.有return最好设置定义一个变量去接受它,接收后这个变量就可以去进行其他操作,或者输出,或者进行运算等等

function getSum(a,b){
            return a+b; ;
    }
    var result=getSum(10,20);
    console.log(result); //30

四、变量

1.全局变量:

  • 声明的变量使用var声明,可以在页面的任何位置使用
  • 除了函数以外,其他位置的变量都是全局变量
  • 全局变量如果页面不关闭,就不会释放,站空间内存
var a=1;//全局变量
        for(var b=2;b<2;b++){
            //全局变量
            console.log("哈哈");
        }
        function f1(){
            var c=1;//不是全局变量
        };
        console.log(a);//1
        console.log(b);//2
        console.log(c);//报错

2.隐式全局变量

  • 声明的变量没有var 声明
  • 隐式全局变量使用delete可以删除
  • 全局变量使用delete不能删除
var a=10;//显式声明的全局变量
        b=20;//隐式声明的全局变量
        console.log(a);//10
        console.log(b);//20
        delete a;
        delete b;
        console.log(a);//10(依然可以输出,说明delete无效)
        console.log(b);//报错
        console.log(typeof(b));//undefined

3.局部变量

  • 在函数内部定义的变量,外面不能使用
    function f1(){
                var c=1;//局部变量
                console.log(c);
            };
            f1();//1
            console.log(c);//报错

4.全局作用域和局部作用域

  • 全局作用域就是全局变量的使用范围
  • 局部作用域就是局部变量的使用范围

5.作用域链

  • 函数变量是从本作用域开始寻找,从里到外
var a=10;
        function f1(){
            var a=20;
            var b=a+a;
            return b;
        };
        console.log(f1());//40
  • 示意图

五、预解析

  • 理解:在解析代码之前做的事,把变量的声明和函数的声明提前到当前所在作用域的最前面。

  • 步骤:

  1. 把变量的声明提升到当前作用域的最前面,只提升声明,不会提升赋值
  2. 把函数的声明提升到当前作用域的最前面,只提升声明,不会提升调用
  3. 先提升var ,再提升function
//正常代码,没有预解析之前
        f1();//前端good!
        function f1(){
            var a="good!";
            console.log("前端"+a);
        };
        console.log(b);//undefined
        var b=10;
//上面的代码通过预解析之后会变成下面这样
        var b;//var 变量声明提前
        function f1(){
            var a;//函数的声明提前,在当前作用域的最前面
            a="good!";
            console.log("前端"+a);
        };//函数的声明提前
        f1();
        console.log(b);
        b=10;
  • 只有用函数声明方式定义的函数才会提升function,函数表达式定义的函数是一个变量,提升var

f1();//报错,因为预解析只提升了var f1;到上面
        var f1=function(){
           console.log("前端")
        };
  • 变量和函数重名,执行函数(表达不准确,主要看代码)

var a;
        function a(){
            console.log("前端大法好");
        };
        console.log(a);//输出上面的a函数,而不是undefined
        a=10;
        console.log(a);//10
  • 如果有多对的script标签都有相同的名字的函数,

    ①如果函数是通过声明定义的,不会受影响

<script>
        function a(){
            console.log("哈哈")
        };
    </script>
    <script>
        a();//嘿嘿
        function a(){
            console.log("嘿嘿")
        };//函数声明会提前
    </script>

    ②如果函数是通过函数表达式声明的,会受影响

<script>
        var a=function(){
            console.log("哈哈")
        };
    </script>
    <script>
        a();//哈哈
        var a=function(){
            console.log("嘿嘿")
        };
    </script>

六、总结

1.argument

  • 当做数组使用,是一种伪数组
  • argument.length可以获取函数在调用传入的个数
function howManyArgs() {
            console.log(arguments.length);
        };
        howManyArgs("string", 45);//2
        howManyArgs();//0
        howManyArgs(12);//1
  • 使用argument[ "   " ] 对象可以获取传入的每个参数的值
function f1(a,b,c,d) {
            console.log(arguments[0]);
            console.log(arguments[1]);
            console.log(arguments[2]);
            console.log(arguments[3]);
            console.log(arguments[4]);
        };
        f1(1,2,3,4);//1 2 3 4 undefined

2.函数也是一种数据类型

  • typeof检测出来的类型是function
function f1() {
            console.log("good!");
        };
        var f2 = function () {
            console.log("nice");
        };
        console.log(typeof(f1)); //function
        console.log(typeof(f2));//function

3.函数参数的类型

  • 函数参数的数据类型可以是数字、字符串、布尔、数组等等
function f1(a){
            console.log(a);
        };
        f1(10);//参数是number
        f1("嘿嘿");//参数是string
        f1(1===2);//参数是Boolean
        f1([10,20,30,40]);//参数是Array
        var i=null;
        f1(i);//参数是null
        var j;
        f1(j);//参数是undefined
  • 函数也可以作为参数使用,如果一个函数作为参数,那么这个参数(函数)就是回调函数
  • 只要看到一个函数作为参数使用,就是回调函数
function f1(fn){
           console.log("我是f1");
           fn();
       }
       function f2(){
           console.log("我是f2");
       }
       f1(f2);//我是f1    我是f2
//注意:是f1(f2),而不是f1(f2())

4.函数可以作为返回值使用

function f1(){
        console.log("我是f1");
        return function f2(){
            console.log("我是f2");
        }
    }
    f1();//我是f1
    var ff=f1();//理解f1()是函数f1里面执行的内容,而f1是这个函数的整个表达式,定义一个变量去接受这个函数的调用
    ff();//我是f1  我是f2 

七、函数案列

//例1:m-n之间所有数的和
    function getSum(m,n){
        var sum=0;
        for(var i=m;i<=n;i++){
            sum=sum+i;
        }
        return sum;
    }
    var result=getSum(1,100);
    console.log(result);//5050
//例2:圆的面积
    function area(r){
        return Math.PI*r*r
    }
    var result=area(3);
    console.log(result);//28.274333882308138
//例3:判断一个数是不是质数;
    function prime(num){
        if(num==2){
                return true;
            }
        for(var i=2;i<num;i++){    
            if(num%i!==0){
                return true;
            }else{
                return false;
            }
        }
    }
    var result=prime(6);
    console.log(result);//flase
//例4:两个数的最大值
    function getMax(a,b){
        return a>b?a:b
    }
    var result=getMax(2,3);
    console.log(result);//3
//例5:三个数的最大值
    function getMax(a,b,c){
        return a>b?(a>c?a:c):(b>c?b:c);
    }
    var result=getMax(2,5,4);
    console.log(result);//5
//例6:两个数的差
    function differ(a,b){
        return a-b;
    }
    var result=differ(6,3);
    console.log(result);//3
//例7:一组数中的最大值
    function getArrayMax(arr){
    var max=arr[0];
    for(var i=0;i<arr.length;i++){
            if(max<arr[i]){
                max=arr[i];
            }
        }
        return max;
    }
    var arr=[1,2,3,4,5];
    var result=getArrayMax(arr);
    console.log(result);//5
//例8:一组数字的和
    function getSum(arr){
        var sum=0;
        for(var i=0;i<arr.length;i++){
            sum=sum+arr[i];
        }
        return sum;
    }
    var arr=[1,2,3,4,5];
    var result=getSum(arr);
    console.log(result);//15
//例9:数组反转
    function rev(arr){
        for(i=0;i<arr.length/2;i++){
            var temp=arr[i];
            arr[i]=arr[arr.length-1-i];
            arr[arr.length-1-i]=temp;
        }
        return arr;
    }
    console.log(rev([1,2,3,4,5]));//(5) [5, 4, 3, 2, 1]
//例10:冒泡排序(从大到小)
    function pup(arr){
        for(var i=0;i<arr.length-1;i++)
            for(var j=0;j<arr.length-1-i;j++){
                if(arr[j]<arr[j+1]){
                    var temp=arr[j];
                    arr[j]=arr[j+1];
                    arr[j+1]=temp;
                }
            }
        return arr;
    }
    console.log(pup([1,5,3,7,4,9]))//(6) [9, 7, 5, 4, 3, 1]
//例11:阶乘和
    function floor(num){
        var sum=1;
        for(var i=1;i<=num;i++){
            sum=sum*i
        }
        return sum;
    }
    var result=floor(5);
    console.log(result);//120
//例12:菲波那契数列
    function rab(num){
        num1=1;
        num2=1;
        sum=0;
        if(num==1||num==2){
            sum=1;
        }
        for(var i=3;i<=num;i++){
            sum=num1+num2;
            num1=num2;
            num2=sum;
        }
        return sum;
    }
    var result=rab(12);
    console.log(result);//144
//输入年月日,返回是这一年的第几天
        function getDays(year, mouth, day) {
            var days = day;
            //如果月份是1月,直接返回天数
            if (mouth == 1) { 
                return days;
            }
            //如果月份是其他月,先定义数组,循环月份求和
            var mouths = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
            for (i = 0; i < mouth - 1; i++) {
                days = days + mouths[i];
            }
            //判断这一年是不是闰年,并且如果月份大于2,多一天
            if (year % 4 == 0 && year % 100 !== 0 && mouth >= 2 || year % 400 == 0 && mouth >= 2) {
                days++;
            }
            return days;
        }
        var result = getDays(2018, 4, 25);
        console.log(result);//115

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!