day 04 函数《有趣的递归函数》

  • day 04 函数《有趣的递归函数》已关闭评论
  • 17 次浏览
  • A+
所属分类:Web前端
摘要

函数
函数概述
函数 实际就是多行代码的抽取(多行代码会构成特定的功能)(方法)
函数的优点
减少冗余代码(重复的代码放在函数里面 在需要的时候调用)函数封装(特定的一些代码使用函数来包
起来),
提高了代码的可维护性及可阅读性
函数的分类
1. 系统函数 window里面的所有函数都属于系统函数 (console.log() alert() prompt()…)
2.内置函数 所有的内置对象里面的函数 都叫内置函数 (Math.pow())
3.自定义函数( 自己定义的函数)
内置函数和系统函数我们更关注于他的使用 自定义函数(定义以及使用)

函数
函数概述
函数 实际就是多行代码的抽取(多行代码会构成特定的功能)(方法)
函数的优点
减少冗余代码(重复的代码放在函数里面 在需要的时候调用)函数封装(特定的一些代码使用函数来包
起来),
提高了代码的可维护性及可阅读性
函数的分类
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)将这个内存空间销毁

函数作用域
作用域
当前一个变量的作用范围 分为局部作用域(在一个函数内声明的 或者是在一段代码块内声明的 他的作
用范围就是当前的代码块)和全局作用域(在对应的全局声明的 他的作用范围就是全局的)

作用域链(个人理解往上面找,找爸爸借钱,不找儿子借钱)

day 04  函数《有趣的递归函数》

 

 

 

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) 然后掏递归公式咯,一下就出来了    

今天的总结完毕咯!!