函数
函数概述
函数 实际就是多行代码的抽取(多行代码会构成特定的功能)(方法)
函数的优点
减少冗余代码(重复的代码放在函数里面 在需要的时候调用)函数封装(特定的一些代码使用函数来包
起来),
提高了代码的可维护性及可阅读性
函数的分类
1.系统函数 window里面的所有函数都属于系统函数 (console.log() alert() prompt()...)
2.内置函数 所有的内置对象里面的函数 都叫内置函数 (Math.pow())
3.自定义函数( 自己定义的函数)
内置函数和系统函数我们更关注于他的使用 自定义函数(定义以及使用)
1.使用function关键词 定义匿名函数(没有名字的函数)(个人感觉用途不是很广,因为,他没有复用价值,只能一次一次的用)
function(形参(可以省略的 可以有多个)){ 函数体(代码) } //直接调用 让别人(事件)去调用(自动调用) (function(){ console.log('匿名函数') })()
2.使用function关键词 定义具名函数 (有名字的函数)(声明试,有名字,可以随便调用)
function 函数名(形参,形参...){ 函数体(代码) } //声明 具名函数(第一种) function sayHello(){ console.log('hello') } sayHello() //传递参数 function sayHello1(name,age){ //形参是形容的参数 console.log('hello'+name+age) } sayHello1('李四') //传进的是实参 根据你要的参数个数来传递对应的参数个数 //调用 // sayHi() //报错 // console.log(sayHi); undefined //具名函数的变种声明 (第二种) var sayHi = function(){ console.log('hi') } sayHi()
3.使用new Function方式(赋值法)
var 函数名 = new Function('形参,形参1','函数体') //定义 var sayBye = new Function('console.log("bye bye!!")') //调用 sayBye() //传参 var sayBye = new Function('username','console.log("bye bye!!"+username)') //调用 sayBye('李四')
在程序执行之前有个预编译过程
预编译
1.他会声明对应的function和var关键词修饰的变量(开辟内存的操作)
2.对应的function的内存空间开辟以后他会将对应的代码块放到其中 等待调用
3.var 修饰的关键词 只会开辟一个空间 并不会进行赋值(默认给他的一个undefined的值)
return
return 返回对应的数据的 他是在函数内容进行数据返回的(当你调用了return操作后 后面的内容将不
再执行)即:只要有return他就会跳出来,不会在执行后面的相关程序了!
function sum(a,b){ return a+b console.log('不会执行的代码') } console.log(sum(1,2))//返回的对应的1+2的结果
如果没有return关键词 返回的一个undefined的值,因为你没有返回值,所以没有返回值,所以sayHi里面啥也没有所以会输出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);//undefined 没有var关键词就10 var a = 30 if(5>4){ console.log(a);//undefined 没有var关键词就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 }
所有的函数都具备arguments (对象)
访问
1.length属性访问长度
2.[] 加下标(从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
注意事项
函数的抽取 (抽取冗余的代码)
1.参数 (可变的内容)
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 //string类型 // console.log(typeof inputValue); 如果是+法操作必须要先转类型 //判断奇偶的操作 if(inputValue%2==0){ console.log('当前为偶数'); }else{ console.log('当前为奇数'); } } //首先需要点击按钮 获取按键 加点击事件 //事件触发自动调用对应的函数 (事件驱动) document.getElementById('btn').onclick = handlerClick </script>
递归算法*
递归可以完成所有循环做的事情 (但是递归的效率较低)
递归三要素
1.找规律
2.找临界值(没有规律的值)return
3.自己调自己(在函数内部调用自己的函数)
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))
示例
// 1 3 6 10 15 21 第100位 前一位+对应的位数 = 这个一位的值 function fn1(n){ if(n==1){ return 1 }else{ return fn1(n-1)+n } } console.log(fn1(6)); // 1 2 3 5 8 13 21 第100位值(递归的效率极低 一般不使用递归 不推荐 (文件的遍历 菜单遍历 深 拷贝)) function fn2(n){ if(n==1){ return 1 }else if(n==2){ return 2 }else{ return fn2(n-2)+fn2(n-1) } } console.log(fn2(7));
bfs 广度优先搜索 dfs 深度优先搜索(递归思想)
作业::递归
//第8题 兔子繁殖问题,设有一只新生兔子,从第四个月开始他们每个月, 月初都生一只兔子, 新生的兔子从第四个月月初开始又每个月生一只兔子按此规律,并假定兔子没有死亡, n(n<=20)个月月末共有多少只兔子? function fn6(n) { if (n <= 3) { return 1 } else { return fn6(n-1)+fn6(n-3) } } console.log(fn6(11)); //3天就可以生一个兔子兔子后面可以一天生一个 function fn7(n){ if(n<=2){ return 1 }else{ return fn7(n-1)+fn7(n-2) } } console.log(fn7(10));
兔子繁殖问题,设有一只新生兔子,从第四个月开始他们每个月, 月初都生一只兔子, 新生的兔子从第四个月月初开始又每个月生一只兔子按此规律,并假定兔子没有死亡, n(n<=20)个月月末共有多少只兔子?(题目解释,有过程)
function fn6(n) { if (n <= 3) { return 1 } else { return fn6(n-1)+fn6(n-3) } } console.log(fn6(11)); //第一列表示月数 第一行表示当前月份中各个月份的兔子的数量 // 1 2 3 4 //1 1 0 0 0 1 //2 0 1 0 0 1 //3 0 0 1 0 1 //4 1 0 0 1 2 //注意这个是第一个兔子生孩子了,所以会有一个还在一月份的兔子 //5 1 1 0 1 3 //6 1 1 1 1 4 //7 2 1 1 2 6//第二个兔子也可以生孩子了 //8 3 2 1 3 9 //9 4 3 2 4 13 //10 6 4 3 6 19 找规律的f(m) = f(n-1) + f(n-3) 然后掏递归公式咯,一下就出来了
今天的总结完毕咯!!