函数
函数概述
函数 实际就是多行代码的抽取(多行代码会构成特定的功能)(方法)
函数的优点
减少冗余代码(重复的代码放在函数里面 在需要的时候调用)函数封装(特定的一些代码使用函数来包起来),
提高了代码的可维护性及可阅读性
函数的分类
系统函数 window里面的所有函数都属于系统函数 (console.log() alert() prompt()...)
内置函数 所有的内置对象里面的函数 都叫内置函数 (Math.pow())
自定义函数( 自己定义的函数)
内置函数和系统函数我们更关注于他的使用 自定义函数(定义以及使用)
自定义函数的定义以及调用
1.使用function关键词 定义匿名函数(没有名字的函数)
function(形参(可以省略的 可以有多个)){
函数体(代码)
}
//直接调用 让别人(事件)去调用(自动调用)
(function(){
console.log('匿名函数')
})()
//直接调用 让别人(事件)去调用(自动调用)
(function(){
console.log('匿名函数')
})()</pre>
匿名函数 (声明比较少 他没有复用价值)
2.使用function关键词 定义具名函数 (有名字的函数)
function 函数名(形参,形参...){
函数体(代码)
}
function 函数名(形参,形参...){
函数体(代码)
}
//声明 具名函数(第一种)
function sayHello(){
console.log('hello')
}
sayHello()
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操作后 后面的内容将不再执行)
2)如果没有return关键词 返回的一个undefined的值
函数执行过程
1.把对应的开辟的function内存里面的代码块丢给方法栈(执行栈)去执行
2.执行栈就会自动取执行对应的方法 执行完返回对应的结果
3.当前结果返回完毕以后 对应的执行栈里面的内存空间要进行回收(GC)将这个内存空间销毁
函数作用域
作用域
当前一个变量的作用范围 分为局部作用域(在一个函数内声明的 或者是在一段代码块内声明的 他的作用范围就是当前的代码块)和全局作用域(在对应的全局声明的 他的作用范围就是全局的)
作用域链
当前的作用域内没有找到对应的变量就会向上去寻找 而这个过程构成的链式结构称为作用域链
var a = 20
function fn(){
console.log(a);//undefined 没有var关键词就20
//优先在同级去找 var a 在 function声明会一起声明,但未赋值,初始值是undefined.
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 (对象)
访问
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
递归算法
递归可以完成所有循环做的事情 (但是递归的效率较低)
递归三要素
找规律
找临界值(没有规律的值)return
自己调自己(在函数内部调用自己的函数)
1) 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))
2)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));
3) 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));