函数是将实现某一功能的代码集合起来,以便重复使用的代码块。
一、函数的创建与调用
//基本语法声明函数及调用
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
来源:https://www.cnblogs.com/wykbk/p/6883321.html