函数
函数的概述
函数 实际就是多行代码的抽取(多行代码会构成特定的功能) (方法)
函数的优点
减少冗余代码 (重复的代码放在函数里面 在需要的时候调用)
函数封装(特定的一些代码使用函数包装起来),提高了代码的可维护性以及可阅读性。
函数的分类
- 系统函数:window里面的所有函数都属于系统函数
如: alert(), isNaN(), console.log(),document.write(), 等 - 内置函数:所有的内置对象里面的函数 都叫做内置函数(Math.pow())
- 自定义函数(自己定义的函数)
系统函数和内置函数我们更关注于它的使用,自定义函数更关注于它的定义和使用。
自定义函数的定义以及使用
1、使用function关键词 定义匿名函数(没有名字的函数)
function( 形参 (可以省略的 可以有多个)){
函数体(代码)
}
//函数调用后面带() 自执行的匿名函数 没有复用价值(只能用一次)
//直接调用 让别人(事件)去调用(自动调用)
function(){
console.log('匿名函数');
}()
匿名函数 (声明较少 没有复用价值)
2、使用function关键词 定义具名函数(有名字的函数)
//声明 具名函数(第一种)
// sayHello() //这个位置成功调用
function sayHello2(name, age) { //形参是形容的参数
console.log('hello,' + name + age)
}
//调用
sayHello2('czh') //传进的是实参 根据你要的参数个数来传递对应的参数个数
//具名函数的变种声明(第二种)
// sayHi() //这个位置报错
// console.log(sayHi); //这个位置打印undefined
var sayHi = function () {
console.log('hi');
}
//调用
sayHi()
//具名函数的两种声明 调用速度来说 对应的第一种方式更快
//function 和 var 在预编译阶段就会声明
//var 关键词修饰的变量在预编译阶段是不会被赋值的(后面的操作会赋值)
3、使用new Function方式
var 函数名 = new Function('形参','形参2','内函数体')
//定义
var sayBye = new Function('console.log('bye bye!!')')
//调用
sayBye()
//传参
//定义
var sayBye = new Function('console.log("bye bye!!")')
//调用
sayBye()
在程序执行之前有个预编译过程
预编译会做的事情
1、他会声明对应的function和var关键词修饰的变量(开辟内存的操作)
2、对应的function的内存空间开辟以后他会将对应的代码块放到其中 等待调用
3、var 修饰的关键词 只会开辟一个空间 并不会进行赋值(默认给他的一个undefined的值)
return关键词
return 返回对应的数据的 他是在函数内进行数据返回的(当你调用了return操作后 后面的内容将不再执行)
function sum(a,b){
return a+b
console.log('这是不会执行的代码')
}
console.log(sum(1,2));//返回的对应的1+2的结果3
如果没有return关键词 返回的一个undefined的值
function sayHi(){
console.log('hi')
}
console.log(sayHi())//undefined
函数执行过程
1、把对应的开辟的function内存里面的代码块丢给 方法栈(执行栈)去执行
2、方法栈(执行栈)就会自动去执行对应的方法 执行完返回对应的结果
3、当前结果返回完毕以后 对应的执行栈里面的内存空间要进行回收(GC)将这个内存空间销毁
函数作用域
作用域:
当前一个变量的作用范围 分为局部作用域(在一个函数内声明的 或者是在一段代码块内声明的 他的作用就是当前的代码块)和全局作用域(在对应的全局声明的 他的作用范围就是全局的)
作用域链:
当前的作用域内没有找到对应的变量就会向上去寻找 而这个过程构成的链式结构称为作用域链
var a = 20
function fn() {
console.log(a);//undefined 没有var就是20
var a = 10
if (10 > 9) {
console.log(a);//10
var a = 30
if (5 > 4) {
console.log(a);//30
var a = 40
if (a > 10) {
console.log(a);//40
}
}
}
}
fn()
函数的arguments(参数数组 参数的集合):
arguments是一个伪数组(有部分的数组特性)(可以通过length对应的长度 [] 下标识来访问里面的元素)
function sum() { //不清楚参数个数(无参)
//arguments 可以接收里面所有的参数
//获取里面传递的所有的参数 arguments 长度length
//下标索引是从0开始的
var result = 0
//遍历对应的arguments里面的所有的参数
for (var i = 0; i < arguments.length; i++) {
result += arguments[i]
}
return result
}
console.log(sum(1,3,5));
所有的函数都具备arguments(对象)
访问
- length属性访问长度
- [] 加下标(从0开始)访问里面的元素
函数的嵌套
- 函数的嵌套: 函数内部可以再包含其他函数。
- 函数之间允许相互调用,也允许向外调用, 但是不可以调用同级函数的嵌套函数。
function fn1(){
console.log('函数1');
function fn2(){
console.log('函数2');
//fn1()没有结果就是死循环
}
function fn3(){
console.log('函数3');
//调用函数2
fn2()
}
fn2()
fn3()
}
fn1()//函数1 函数2 函数3 函数2
注意事项
函数的抽取(抽取冗余的代码)
-
参数(可变的内容)
-
返回值(我们想从这个函数得到什么)
Dom的简单操作
1、获取对应的标签(通过id获取)
document.getElementById('id的属性值')
2、input框的值获取 value属性
document.getElementById('input框的id').value//得到input框内的值
3、点击事件onclick
element.onclick = function(){
//相关控件
}
示例(以事件作为驱动)
<!-- 通过输入框输入数值判断对应的奇偶并打印 -->
<input id="number" type="text">
<button id="btn">判断奇偶</button>
<script>
function handlerClick() {
//拿到input框里面的内容 获取input框
var inputValue = document.getElementById('number').value
// console.log(typeof inputValue);//如果是加法操作 必须要先转类型
//判断奇偶的操作
if (inputValue % 2 == 0) {
console.log('当前为偶数');
} else {
console.log('当前为奇数');
}
}
//首先需要点击按钮 获取按钮 加点击事件
//事件触发自动调用对应的函数(事件驱动)
document.getElementById('btn').onclick = handlerClick
</script>
递归算法
递归三要素:
- 找规律
- 找临界值(没有规律的值)return
- 自己调自己(在函数内部调用自己的函数)
2 4 6 8 10 第100位的值是什么
function fn(n){//一般情况下都会有参数 n表示位数
if(n==1){//没规律的(一般在前面或者后面)
return 2 //返回具体的值
}else{//有规律的 返回对应的规律的公式
return fn(n-1)+2
}
}
console.log(fn(100))
bfs广度优先搜索 dfs深度优先搜索(递归思想)