函数(Function)---声明、定义、事件、作用域、递归

了解函数

  • 函数就是把特定功能的代码抽取出来并进行封装,用来重复执行一些功能,并起个名字(函数名)。函数对任何语言来说都是一个核心的概念。通过函数可以封装任意多条语句,而且可以在任何地方、任何时候调用执行

  • 使用函数的好处,为什么要使用函数

    • 函数可以重复执行某一部分代码(通过函数名调用)
    • 使程序变得更简短而清晰
    • 有利于程序维护
  • 什么时候需要函数
    • 当相同的代码出现多次时
    • 当需要提取公共代码时

封装:1-100随机数,把重复性的代码写到函数中

<script>

        /*
            封装:1-100随机数
            把重复性的代码写到函数中
            * Math.random();//0-1(不等于1)
         */

        function randomNumber(){
            var number = parseInt(Math.random()*100)+1;
            console.log(number);
        }

        // var number1 = parseInt(Math.random()*100)+1;
        // var number2 = parseInt(Math.random()*100)+1;

        // 函数的执行
        // 格式:函数名()
        randomNumber();
        randomNumber();
        randomNumber();
        randomNumber();

    </script>

函数的声明

  • 仅仅是将函数保存到内存中
  • 函数声明注意事项:
    • 避免与变量重名
    • 声明提前
  • 浏览器在逐行解析代码前,会把变量声明和函数声明事先保存在内存中
    • 函数声明
    • 变量声明(变量声明但不赋值,默认值为undefined)

函数的定义

  • 关键字声明(声明式)

函数的声明会提前 ==> 解析器会率先读取函数声明,并使其在执行任何代码之前可用(可以访问);

//格式:funtion 函数名(){}
function show(){}
  • 函数表达式(赋值式)
//show();不能这样写
//格式:
var show = function(){}
show();
/*不能在赋值式之前使用show(),show()在前面时只声明了show(相当于var show;)但是show未被赋值此时show的值为undefined,undefined()不是一个函数会报show is not a function错*/
  • 报错会阻止代码向下执行
    * 浏览器解析代码步骤
    1. 把变量声明和函数声明事先保存到内存中
    2. 逐行执行代码

    * show2 is not a function
        * 单词写错
        * show2不是一个函数
    

函数的执行

1.手动调用sum();
2.事件驱动:
格式:元素.事件 = 函数名;
btn.onclick = sum;

常见事件触发函数

  • onclick:点击事件
  • ondblclick:双击事件
  • onmouseover:鼠标移入事件
  • onmouseout:鼠标移开事件
  • onchange:内容改变事件(一般用于表单元素)
  • onkeyup:键盘按键弹起事件

页面加载事件:页面<所有内容>加载完毕后执行(元素、图片、视频、音频..)

console.log(111);
window.onload = function(){
    console.log(666)
}
console.log(123);

控制台打印效果是111 123 666

变量的作用域

俗称使用范围,变量能够使用的范围,分<全局作用域>和<局部作用域>

  • 全局作用域
    • 在全局作用域中定义的变量称为全局变量
  • 局部作用域
    • 在局部作用域下定义的变量称为局部变量(函数内定义的变量是局部变量)
  • 变量查找规则
    • 就近原则(如查找变量a)
      • 使用变量a时先从当前函数查找,如果当前函数有变量a则使用;
      • 如果当前函数无变量a,则往父级函数查找,如果找到则使用,并停止查找;
      • 如果在父级函数还是无法找到,则继续往上一层函数查找,以此类推,直到最顶层(全局作用域),如果还是没找到,则报not defined错误;
var className = 'h5_1704';
windows.onload = function(){
    var myName = 'emon';
    //声明函数
    function showMsg(){
        var myAge = 22;

        document.write('大家好,我叫' + 'myname' + '今年'+myAge+'岁,我在' + className)
    }
    //调用函数
    showMsg();
    //在函数外使用函数内的变量会报错
    console.log('myName');
    //console.log('myAge');
}
  • 作用域链:每个函数在定义时就形成了局部作用域,如果存在多个函数嵌套,他们之间就会建立起某种联系,直到全局作用域,这种联系称之为作用域链。当函数访问变量时,根据就近原则在这个作用域中从内到外查询变量。
    作用域链

声明提前

  • 函数声明提前
  • 变量声明提前

    > 声明但没有赋值的变量默认为undefined
    

/*声明提前
    提前到当前作用域顶部
*/
var num = 10;
function sum(){
    //var num;
    console.log(num);//输出的结果是undefined
    var num = 30;
}

函数的参数

  • 函数的参数:局部变量
  • 形参和实参的区别:
    • 形参:声明函数时圆括号定义的变量
    • 实参:函数执行时传入的函数

形参和实参的数量可以不同

  • arguments
    函数内部隐藏的对象(是一个类数组),保存这实参的信息
    • length:实参的数量
    • callee:对函数本身的引用
  • 引用数据类型与基本数据类型的传参(引用传递与值传递)
    • 函数作为参数传递
<title>封装一个函数,计算所有传入参数的和</title>
<script>
        /*
            数组:可以保存多个数据的变量 
            格式:var arr = [10,20,30]
            * 索引:标识某个数据的位置
                * 索引值从0开始
                * 读取:arr[索引值]
            * length:表示数组的长度
         */
        var arr = [10,20,30];
        //console.log(arr[2])

        // 函数内部隐藏的对象(是一个类数组),保存着实参的信息
        function sum(){
            // console.log(arguments);
            // var res = num1 + num2;
            // console.log(res);

            // 存放结果
            var res = 0;

            // 循环
            for(var i=0;i<arguments.length;i++){
                res += arguments[i]
            }

            console.log(res);
        }

        // sum(10,20);
        // sum(12,11);
        // sum(1,2,3);
        sum(1,2,3,4,5,6,7,8,9);
    </script>

函数中的this

函数中的this是一个关键字,表示当前对象,而当前对象是谁取决于谁调用了这个函数

<script>
    window.onload = function(){
    //这里的this是window
        function showMsg(){
        //这里的this指向的是window
        console.log(window);
        }
    showMsg();
    }
</script>

函数递归

函数可以自己调用自己,成为函数的递归调用。(要避免死循环)
递归调用的过程:
1.首先去找临界值,即无需计算就获得的值(一般返回该值)
2.找这一次和上一次的关系(一般从后往前找)
3.假设当前函数已经可以使用,调用自身计算上一次的运行结果,再写出这次的运行结果
例1:求任意数字的阶乘

function factorial(n){
    if(n==1){
    return 1;
    }
    return n*factorial(--n);
}

例2:递归实现斐波那契数列

function fib(n){
    if(n==1 || n==2){
        return 1;
    }
    return fib(n-1)+fib(n-2);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值