函数
概述
函数是抽取的公共代码块,主要是为了复用。函数相当于一个工具需要的时候就可以调用,当我们没有 这个工具就需要自己封装。
函数的分类
- 系统函数 (console.log、 toString parseInt 等 )
- 内置函数 (Math.pow等)
- 自定义函数 (自己定义的函数)
函数的定义
- 使用function关键词声明定义
匿名函数的定义(没有函数名的函数 无法被复用)
function(){
代码块
}
具名函数的定义 (有函数名的函数 必须调用才会执行 可以复用)
function 函数名(){
代码块
}
函数名(函数调用)
用new 关键构建函数对象(不推荐)
var 函数名 = new function(){
代码块
}
函数名(调用)
预编译机制
- var关键词修饰的变量会进行预编译过程
- function 也会进行预编译过程
- 变量的默认值为 undefined
- 函数的默认值 是函数本身
- 在提升时,只提升到当前作用域的顶部
- 当变量名和函数名重合时,只保留函数
- 声明变量没有var,就不会进行提升 会报错
概述
预编译指的是js引擎预先编译,它主要针对的是两个。第一个使用var关键修饰的变量会进行预编译,第二个使用 function修饰的函数会进行预编译。
执行过程
函数声明会发生预编译
调用的时候,他会去寻找对应的堆空间的函数引用
然后再将它推入执行栈中 进行执行
在执行中会打开对应的函数内的代码进行执行
当他执行完毕以后 那么gc就会将它回收(可达性)
回收过程
gc是一个垃圾回收机制(用于回收当前没有被使用的变量) 回收器
回收器
主回收器 Major gc(常用的) 副回收器 Manor gc
回收机制
标记清楚 (设置true false标志) 引用计算 (引用操作进行++)
注意事项
- var关键词不包含赋值过程
- 函数的预编译会比var关键词慢 如果var关键词修饰的变量和函数名同名,那么在预编译的时候函数会覆盖var。
函数支持传入参数
关键词
形参
- 形容的参数
- 不需要var
- 遵循变量的命名规则
- 不需要声明形参的数据类型(js是弱类型语言) )
- 当没有传实参时,默认值是undefined,不会报错
实参
- 实际的参数 (实际的值)
- 实际参数,在调用的时候传入数据,可以是任何数据
函数的参数定义
function 函数名(形参1,形参2,形参3....){
代码块
}
在定义函数的时候,需要考虑特殊情况
函数传入的实参可变
// 函数的实参个数可变 (多传 少传)
function fn(a, b, c) {
console.log(a, b, c)
}
//多传实参 (避免的)
fn(1,2,3,4)
//少传实参 默认没传的参数的值为undefined
fn(1)
return 关键词
return关键词是用于返回值的,默认函数没有return的情况下返回的值为undefined 返回函数执行后的结果,在函数的调用位置 会结束函数的执行,遇到return后,即使后面还有别的js语句,也不会执行了交回函数的执行权
注意事项
- return关键词用于返回对应的function的值,默认没有return返回undefined
- return 关键词用于返回对应的fu
- return会退出当前的function执行,function内的后续代码不再执行
- return 结束当前function ,throw new error是结束当前的执行程序
- break (用于跳出循环代码块或switch代码块) 和 continue (跳过本次循环)
arguments
arguments是一个伪数组(存储多个值的一个列表),主要是接收对应的传入的实参。它是一个内置对象。它存在于function中。
arguments的特点
- arguments存在于function中 (只能在function里面使用)
- arguments的长度通过length属性来获取 (arguments.length 获取长度)
- arguments具备下标,通过下标可以访问对应的arguments里 面的元素(下标从0开始 到arguments.length-1结束)
- 如果使用arguments来获取实参,那么对应的形参就不需要定义
作用域及作用域链
作用域
一个变量的作用范围称为作用域
作用域的划分
全局变量和局部变量的分界线,以函数为界
全局作用域
- 在函数外声明
- 全局和局部都可以访问全局声明
- 在函数内部声明变量不加var,就是全局变量,不推荐使用
局部作用域
- 在函数体内加var声明的变量
- 只有在局部才可以访问,也就是在函数内部
- 形参是局部变量
全局作用域可以在全局访问 局部作用域只能在局部访问 外部不能访问
作用域链
根据作用域查找对应的变量的过程称为作用域链
事件的简单理解:
用户行为事件:
-
onclick单击事件
-
ondblclick双击事件
-
onfocus获取光标事件
-
onblur失去光标事件
-
window.onload页面加载完成后才执行
-
onmousedown鼠标按下
-
onmouseup鼠标抬起
-
onmouseover鼠标移入
-
onmouseout鼠标移出
【注】鼠标在父元素和子元素之间互相移入移出 会触发
- onmouseenter鼠标移入
- onmouseleave鼠标移出
【注】鼠标在父元素和子元素之间互相移入移出 不会触发
- onmousemove鼠标移动
事件驱动
-
利用dom操作中的事件来执行对应的方法
-
获取dom元素
document.getElementById(id选择器名字) //根据id获取元素 -
获取input框的值 value属性
<!-- 使用事件驱动 onclick 点击事件 当你点击按钮的时候 自动执行handler函数 事件驱动 -- > <button onclick="handler()">获取input框的值</button> <input type="text" id="input"> <script> function handler(){ //获取input框 var input = document.getElementById('input') //打印input框的值 console.log(input.value) } </script>
递归 (Ologn)
递归是一个基础算法,它可以完成任何循环可以完成的操作。
递归的用途(可以在不知道层级的情况下去走到底)
- 文件目录遍历
- DFS查找
- 多级对象分析合并
- 深拷贝
递归三要素
-
找初始值(没有规律的值)
-
找规律
-
自己调自己 (在函数内部调用自己这个函数) 简单递归
function fn(参数){ if(没有规律的条件){ //返回没有规律的值 }else{ //返回有规律的值 自己调用自己 } }