javascript--函数(一)
函数是将实现某一功能的代码集合起来,以便重复使用的代码块。
一、函数的创建与调用
//基本语法声明函数及调用 function obj(){ alert(1) } obj() //字面量定义函数(匿名函数的自调用) (function(){ //函数功能代码块 })() //对象形式声明函数 <body> <div onclick="fname3()" style="background: red;width: 100px;height: 100px"></div>
<!--事件调用--!> </body> <script> var fname3=new Function("alert(1)"); </script>
注意:以基本语法声明的函数,会在页面载入的时候提前解析到内存中,以便调用,所以可以在函数的前面调用,这里涉及到js中的预解析顺序,但是以自变量形式命名的函数,会在执行他的时候,才进行赋值,所以只能在函数的后面调用。
二、函数的参数
1.参数的作用:可以动态的改变函数体内对应的变量的值,使同一函数体得到不用的结果。
形参:在定义函数的时候,函数括号内定义的变量叫做形参,用来接收实参的
实参:在调用函数的时候,在括号内传入的变量或值叫做实参,用于传递参数
2.参数的详解
1)参数的类型
可以是任何的数据类型
2)参数的个数
实参和形参的数量相等,一一对应
实参小于形参,不会报错,多出的形参值自动赋值undefined
实参大于形参,不会报错,arguments对象进行获取
3)arguments
每创建一个函数,该函数就会隐式创建一个arguments对象,包含实际传入参数的信息
arguments对象的属性
——length 获得实参的个数
——callee 获得函数本身的引用
——访问传入参数的具体值,arguments[下标]
function aa(a,b,c,d) { console.log(arguments) console.log(arguments.length) console.log((arguments[3])) console.log(arguments.callee) } aa(1,"qwq",4)
4)参数最多有25个
三、函数的返回值:函数的运行结果
通过return语句给函数一个返回值,停止并跳出当前函数
return语句的返回值:
1)任何函数都有返回值,默认返回值为undefined
2)一个函数可以有多个返回语句,但只能有一个返回值
3)外部引用函数内部值需要返回函数值
function obj(a,b){ var num=a+b; } console.log(obj(1,2)); //undefined //外部引用函数内部值需要返回值 function obj(a,b){ var num=a+b; return num; } console.log(obj(1,2)); //3
四、函数的运行环境
1)作用域、作用域链
作用域:变量在某个代码段范围内有意义
作用域链:函数在运行时隐式的创建一个集合,该集合保存函数可见范围内的所用变量与对象,这个集合即为作用域链。
2)运行环境
宿主环境:浏览器
执行环境:执行的环境决定了变量和函数的作用域
a.全局环境:window
b.局部环境:函数内部
3)全局变量、局部变量
提高程序的逻辑性与安全性(var使得函数内部变量的改变不影响全局变量的值,函数外部不可访问函数内部的值)以及内存放释放(函数执行完毕,垃圾回收机制将内存中的变量删除)
全局变量:在页面中任何地方都能够访问得到的变量,拥有全局的作用域
函数的最外层定义的变量、没有定义直接赋值的变量拥有全局属性
局部变量:只能在固定的代码片段(函数片段)中访问得到
函数内部定义的变量就是局部变量,参数也是局部变量。
五、函数的预解析
js预解析是否有语法的错误、标点符号的错误、内存中是否有足够的空间存储变量和函数(必须要做的事)
1)script块依次解析,从上到下连成一片,依次下边的script块内可以调用上边script块内的函数
2)每个script块内对标识符(关键字)进行解析,将var 声明的变量和function解析到script块的开头,解析的顺序就是书写的顺序,var解析的变量无赋值
3)函数内部依次解析变量与function,将其解析到函数的开头。
//函数中声明的变量可以是全局变量,在第一次调用的时候使用 var nub=200; function fun(){ var nub=300; console.log(nub); } fun() console.log(nub); //300 200 //注意函数中全局变量对局部变量的影响 var nub=200; function aa(){ var nub=300; function bb(){ nub=400; console.log(nub); //nub=400 } bb(); console.log(nub) //nub=400 } aa() console.log(nub); //400 400 200 //变量可在作用域链上对局部变量进行覆盖赋值 var nub=200; function aa(){ nub=300; function bb(){ nub=400; console.log(nub); } bb(); //变量没有申明直接赋值为全局变量 var nub=200; function aa(){ var nub=300; function bb(){ nub2=400; // 变量没有申明直接赋值为全局变量 console.log(nub); //变量在作用域链上查找值 } bb(); console.log(nub) } aa() console.log(nub2); //300 300 400 //预解析将变量解析在开头 //首先进行js的预解析,var nub,var str,var arr解析在开头 //if满足条件为arr={},是一个空对象,而var str只声明,无赋值,因此不会报错,为ubdefined var nub=200; if(nub<200){ var arr=[] }else{ var obj={} } console.log(arr,obj) //undefined Object //在没有条件语句的情况下执行 var arr=[]; var obj={}; console.log(arr,obj) //数组对象、空对象 //函数的调用 function aa(){ var num=10; return function(){ console.log(num++); } } var fn=aa() //变量存储的是函数aa的返回值函数 fn() //调用的是返回函数 返回值为10,num++先输出在赋值 fn() fn() console.log(num) //报错,num为局部变量,外部不可访问 //10 11 12 报错 //js的预解析会将同名的变量或函数进行覆盖,变量只解析var 声明,无赋值,而函数将全部解析在环境开头。 console.log(a) //function a(){console.log(4)} var a=1; console.log(a) //1 function a() { console.log(2) } console.log(a); //1 var a=3; console.log(a); //3 function a() { console.log(4) } console.log(a) //3 a() //报错 //函数内部全局变量不会进行解析(无声明直接赋值) var a=1; function fun(a) { console.log(a) //1 a=2; } fun(a); console.log(a) //1