任意程序代码进行封装,需要用的时候进行调用,函数的封装:封装了一段或多段被重复调用的代码块,目的:让大量代码重复使用
- 函数定义方式
函数关键字(声明式)定义(命名函数) function 函数名(){封装的程序代码} 函数调用:函数名() 赋值式定义(字面量)(匿名函数) 匿名函数可以作为函数的参数 var (变量名) = function(){封装的程序代码} 函数调用:变量名()
- 函数参数
定义:在函数内部:某些值不能固定,可以通过参数再调用函数时传递不同的值进去,函数传参的过程本质就是给形参变量赋值,是不用声明的局部变量
参数就是一个变量(形参)和值(实参)
实参>形参:多的形参忽略掉
形参>实参:多的形参输出是undefined数据类型(未定义的,未赋值)
参数默认值技巧:
function printStar(num) { var num = num || 5}
- arguments
是当前函数的内置对象(只要函数才有arguments对象,而且每个函数都内置好了),arguments对象存储了传递的所有实参[]以伪数组的形式存储,没有数组常用方法,可以遍历
function fn(){ console.log(arguments)//里面存储了所以传递过来的实参[]伪数组的形式 console.log(arguments.length) console.log(arguments[0]) } fn(1,2,3,4)
- return语句(函数返回值)
没有值:返回undefined(未定义的) 没有return也返回undefined
有值:将值返回给函数调用语句,遇到return都会停止后面的代码(类似bark) 后面一般不跟代码,只能返回一个值 num1,num2(返回最后一个) 返回多个值可以数组
- js作用域
就是代码名字(变量)在某个范围内起作用和效果--为了提高程序的可靠性和命名冲突(不同作用域相同变量名不会冲突)
函数体中可以访问函数外面变量
函数体外不能访问函数内变量
一、全局作用域
整个script标签或者一个单独的js文件
二、局部作用域(函数作用域)
在函数内部就是局部作用域(这个代码的名字只在函数内部起效果和作用)
三、变量作用域:根据作用域不同分为全和局
1、全局变量
在全局作用域下生明的变量(script标签下的变量)
如果在函数内部直接赋值没有声明的变量也是全局变量
2、局部变量
在局部作用域下声明的变量(函数内部的变量)
形参也是局部变量
3、执行效率
全局变量只要浏览器关闭的时候才会销毁
局部变量当程序(函数)执行完毕就会销毁 节约资源
- 作用域链
一、变量访问规则
首先在自己作用域>>>如果没有在上级作用域找>>>如果还是没有继续上级,直到全局作用域查找>>>如果全局作用域也没有就报错(typeof 变量 undefined)
二、变量的赋值规则
在自己作用域查找变量,如果找到直接赋值>>>没找到在上级作用域查找,直到全局作用域查找>>>如果全局作用域也没有,自动创建一个变量再给他赋值
- 预解析
浏览器(js引擎)执行源代码之前,会对源代码进行预处理,这种操作称预解析
1. 声明式定义的函数提前 (赋值式定义的函数不提前)
2. var 声明的变量提前 (值不会提前)
函数名不要和变量名相同,函数优先被访问,如果变量在前,会把变量当作函数,下面的函数调用当作变量
变量预解析(变量提升) 把所有的变量声明var提升到当前作用域最前面,提升示赋值 var a=b=c=9== var a=9;b=9;c=9 (bc是全局变量) var a=9,b=9,c=9==var a=9 var b=9 var c=9 函数预解析(函数提升) 函数表达式定义会提前 因为var声明 变量提前 会提前 但是函没提前 var fn fn=function(){} 函数关键字定义会提前 全部提升 function(){}
- 递归函数
将函数调用语句写在函数体内,自己调用自己,称为递归函数
函数中也要有改变递归函数执行条件(循环也要有改变循环的条件),否则会死递归
一、执行栈
运行过程中有个栈保存的过程 一层层的弹
也叫调用栈,具有LIFO(Last in, First out 后进先出)结构,用于存储在代码执行期间创建的所有执行上下文
二、递归的缺点
递归会层层嵌套 层层返回 效率不高
function fb(n) { if (n == 1 || n == 2) { return 1 } return fb(n - 1) + fb(n - 2) } var f = fb(9) console.log(f);
函数(function) 复杂数据类型
于 2022-04-29 18:03:33 首次发布