函数
04:函数
一、函数的基本概念
- 函数的概念
- 函数,即功能。将实现了某个功能的代码,集中起来,通过函数语句进行封装,封装之后,可以选择直接执行或行为 的 代码段。
- 函数是一种数据类型:function
- 对象:数据的打包,函数:代码的打包
- 函数最大的意义:封装功能
- 函数的特点:
- 重复使用
- 选择使用
- 忽略细节
二、函数的使用
- 创建函数
- 声明式:使用function关键字创建函数
- function 函数名(){}
- var 变量名
- 赋值式:配合变量,赋个函数值,将函数作为一个值或表达式使用
- var 变量名 = function(){}
- 将函数作为值使用
- 声明式:使用function关键字创建函数
1 | // 固定语法: |
- 使用函数 - 执行函数
- 直接执行:函数名()
- 任何正在执行空间下,任意位置,只要函数名后有小括号,函数都会立即执行
- 行为执行:
- 事件源.on事件类型 = 函数名;
- btn.onclick = fn
- 事件源.on事件类型 = 函数值;
- btn.onclick = function(){}
- 事件源.on事件类型 = 函数名;
- 直接执行:函数名()
- 根据函数的写法,做函数分类
- 有名函数
- 声明式创建的函数:function 函数名(){}
- 正常函数,可以正常使用
- 无名函数
- 没有名字的函数:function(){}
- 无法直接使用,只能作为 值 或 表达式 使用
- 作为赋值式创建函数的值:var fn = function(){}
- 作为事件处理函数使用:btn.onclick = function(){}
- 作为函数的参数使用,叫回调函数:fn( function(){} )
- 作为函数的返回值使用,叫闭包函数:
- function fn(){ return function(){} }
- 作为匿名函数的函数体:(function(){})()
- 匿名函数:(function(){})()
- 会自动执行
- 用来生成新的作用域
- 有名函数
四、函数的入口 - 参数
- 实参:写在函数执行时的小括号内,用来发送参数,类似于值
- 形参:写在函数创建时的小括号内,用来接收参数,类似于变量
- 关系:类似于变量赋值,实参传给了形参,实参赋值给了形参,形参保存了实参
- 个数:任意个
- 形参和实参数量一致:从左向右,一一对应
- 形参多,实参少:多出来的形参是undefined
- 形参少,实参多:多出来的实参没有形参接收,可以找arguments获取
- 类型:任意类型
- 当参数为另一个函数时,作为参数的这个函数,叫回调函数
- arguments
- 是函数内部专用的一个内置对象,用来接收所有实参
- 数组的形式,有索引(从0开始)和长度(xxx.length)
- 借助循环遍历arguments中所有的数据
- arguments和形参的应用场景
- 当函数的参数个数确定时,使用形参
- 当函数的参数个数不确定时,使用arguments
五、函数的出口 - 返回值
- 返回值的意义:将函数内部的执行结果,在函数外部获取到,方便二次使用,或另作他用
- 如何创建返回值:
- 关键字:return
- 语法:return 要返回的数据或变量
- 函数如果没有return,返回的是undefined,如果有return,返回的是return后的数据
- 个数:一个
- 一个函数只能执行一次return,一个return只能返回一个数据
- 类型:任意类型
- 当返回值为另一个函数时,返回的这个函数,叫闭包函数
- return的功能
- 给函数返回值
- 结束当前函数
- 返回值的应用场景
- 需要在外部获取函数内部数据的时候,需要给函数添加返回值
- 做功能的函数可以不需要返回值
- 做数据处理的函数必须要有返回值
- 返回值,返回到哪?返回到函数的执行语句身上,整个函数的执行语句,就是函数执行后的返回值
六、函数的应用
- 封装 打印n行m列表格的功能 函数
- 封装 计算任意三个数字的和 函数
- 封装 计算任意个任意数字的和 函数
- 封装 计算任意个任意数字的积 函数
- 封装 计算任意个任意数字的平均数 函数
- 封装 计算任意两个数字的(和,差,积,商,余)的 函数
- fn( 10, 3, “+”)
- fn( 10, 3, “-“)
- fn( 10, 3, “*”)
- fn( 10, 3, “/“)
- fn( 10, 3, “%”)
- 封装 任意三个不同数字比大小,并从小到大的顺序打印的 函数
- 穷举法:列出所有可能性
- 参数
- 封装 已知一个四位数,要求每位加5之后和10取余代替该数字,第一位和第四位交换,第二位和第三位交换,传入四位数,返回处理之后的数字 函数
- 参数
- 返回值
七、作用域
- 作用域:变量或函数生效的区域
- 分类
- 全局作用域:不属于任何一个函数的区域
- 局部作用域:属于某个函数的内部区域
- 作用域可以嵌套:父子作用域
- 作用域没有嵌套:兄弟作用域
- 作用域的使用规则
- 父作用域不可以操作子作用域中声明的变量
- 子作用域可以操作父作用域中声明的变量
- 兄弟之间不能互相操作对方内部声明的变量
- 作用域链的规则:多层作用域嵌套时
- 在某个作用域内使用变量时,会先在自身作用域查找,找不到,向上层作用域查找,依次到全局作用域,任意一层找到了,就使用,停止查找,直到全局都没找到,…
- 获取:报错
- 赋值:自动创建到全局
- 类似于不声明变量,直接赋值
- 不符合逻辑的做法,是一种缺陷,在下个版本的严格模式中被修复,修复成报错
- 在某个作用域内使用变量时,会先在自身作用域查找,找不到,向上层作用域查找,依次到全局作用域,任意一层找到了,就使用,停止查找,直到全局都没找到,…
- 变量的生命周期
- 局部变量:跟随局部作用域的创建声明,局部作用域的结束被释放
- 朝生暮死
- 全局变量:跟随程序的执行,一直存在
- 一般情况下,推荐使用局部,尽量少用全局
- 小技巧:利用匿名函数包裹整个代码文件,将所有的变量和使用函数都放在匿名函数内
- 匿名函数:
(function(){})()
- 自动执行
- 注意:匿名函数前后最好加上分号
- 局部变量:跟随局部作用域的创建声明,局部作用域的结束被释放
八、声明提升
- var声明的变量
- 提前到当前作用域最开始的位置声明,原位赋值
- function声明的函数
- 提升到当前作用域最开始的位置,整体提升
- 赋值式创建函数
- var fn = function(){}
- 提升的是var声明的变量,没有提升函数
- var声明的变量和function声明的函数重名了(重名自身就是错误声明)
- var提升的更高
- 所以function覆盖了var声明的空间
- 最终是function生效
- 练习
九、函数事件执行
- 语法:
- 元素.on事件类型 = 函数名
- 元素.on事件类型 = 无名函数
- 获取元素:js选择器:id选择器
- var ele = document.getElementById(“id名”)
- 事件类型:行为类型:动作类型
- 鼠标类:任意元素
- 左键单击:click
- 左键双击:dblclick
- 右键单击:contextmenu
- 按下:mousedown
- 抬起:mouseup
- 进入:mouseover / mouseenter
- 离开:mouseout / mouseleave
- 移动:mousemove
- 键盘类:只能加给能获取焦点的元素
- 按下:keydown
- 抬起:keyup
- 表单类:表单控件
- 获取焦点:focus
- 失去焦点:blur
- 输入:input
- 内容改变:change
- 提交:submit
- 重置:reset
- 浏览器:window
- 加载:load
- 滚动:scroll
- 改变大小:resize
- 鼠标类:任意元素
- 测试事件时注意以下问题:
- 事件源,事件的触发方式,事件触发之后的效果体现
- 谁的什么事件,如何触发,触发之后有什么效果
十、递归
- 其实就是一种函数的调用方式:在函数内部执行自身
- 递:向内执行
- 归:向外返回
- 递归必须要有一个递的终点、归的起点,否则会成为死递归,等同于死循环,瞬间浪费大量性能,造成程序崩溃,计算机卡死
- 递归的特点
- 浪费性能
- 内存泄漏
- 利用递归的思想解决重复执行的问题,可以节省大量代码
- 不建议使用
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 !
评论