1.函数的定义和概念
把一段相对独立的具有特定功能的代码块封装起来,形成一个独立实体,就是函数,起个名字(函数名),在后续开发中可以反复调用
函数的作用:
1.使代码变得清晰简单
2.有利于维护
3.可以提高开发效率
4.提高了代码的重用性
5.可以控制代码的执行时间和执行场景
function 函数名(形参1,形参2......形参n){
// 函数主体
}
var 函数名=function(形参1,形参2......形参n){
// 函数主体
}
2.函数的分类
1)有名函数
2)匿名函数 没有名字的函数 想要调用只能自调用
3)内置函数
4)用户自定义的函数
3.函数的参数
例如需要求n个数的和 n可能取值取不同的数 有的时候是10 有的时候是100
这个时候有函数的参数就能解决这个问题
function sum(a){
var sum=0;
for(var i=1;i<a;i++)
{
sum+=i;
}
alert(sum);
}
sum(15);
sum(24);
4.函数的三个内置属性或者方法
1)arguments 当函数的参数过多的时候,比如10个,20个......
形参都写出来 会显得很乱 arguments用于解决函数参数过多的问题
arguments相当于一个伪数组,拥有数组的下标和length,但是没有数组的方法
例如
function sum(){
var sum=0;
for(i=0;i<arguments.length-1;i++)
{
sum+=arguments[i];
}
alert(sum);
}
sum(1,2,80,64,5,10);
2)return 函数的返回值 没有返回值的情况下,函数只能在内部打印或者输出或者弹出内容,但是我们如果想在另一个函数中使用这个值的话就会很不方便,所以衍生出了函数返回值return
1.函数默认返回值为undefined
2.当rerun返回多个值的时候,可以用数组的方式返回
3.return可以返回任意类型的数据
4.return后面的代码不再执行 return相当于break在循环中的作用
5.函数设置return 返回值需要有东西(变量)来接收
3)this this一般指其父对象,当函数中存在于全局(<script></script>)中的时候,返回this,只能返回window顶级对象
而当函数存在于对象中,属于对象的方法的时候this指的就是这个对象,而当构造函数(返回对象)的时候,this特殊运用,指返回的对象
5.作用域
1)全局变量
定义在全局<script></script>中的变量
2)局部变量
定义在函数中的变量(es5)在es6中,if,for,while循环内部的也是局部变量 声明变量的方式有所改变 用let声明变量
3)隐式全局变量
定义在函数作用域中的没有定义的变量
6 预解析
可以理解为在脚本正式执行之前的一个先行的一个解析的过程 这个过程中会将全局变量 局部变量(不包括函数中的变量)拿到预解析的环境中,如果预解析的时候,拿到 的变量有赋值,正式执行的时候便会执行这一行,如果预解析的时候没有赋值,那么便会跳过这一行
例子:
var num = 10;
fn1();
function fn1() {
console.log(num);//undefined
var num = 20;
}
函数fn1执行的时候,由于函数内部存在有定义的num 所以并不会那外面的num 可以理解为外面一个大的预解析环境 里面有 var num; 然后函数作用域里面有一个小的预解析环境 var num 所以在执行函数的时候 就会输出undefined
而如果代码是这样的 则会输出10
var num=10;
fn1();
function fn1(){
console.log(num); // 10
}
例子:
fn3();
console.log(c); // 9
console.log(b); // 9
console.log(a); // 9
function fn3() {
a = b = c = 9;
console.log(a); // 9
console.log(b); // 9
console.log(c); // 9
}
fn3执行的时候 定义的a,b,c 相当于定义了三个隐式全局变量 又先执行了fn3所以发生了对全局变量的赋值,所以会打印六个9
例子(面试题):
- alert(a);
- var a;
- alert(a);
- function a(){
- alert(1);
- }
- alert(a);
- var a = 2;
- alert(a);
- function a(){
- alert(3);
- }
- alert(a);
- function b(){
- alert(4);
- }
- alert(a);
预解析:
第二行拿出 var a;
第四行拿出function a()(alert(1)); 覆盖上面
第八行拿出 var a;覆盖上面
第十行拿出function a(){alert(3)};覆盖上面
// 如果有再次定义的变量 var a=20; 由于优先级的问题 并不能覆盖上面
第十四行拿出function b(){alert(4)}
执行:
第1,3,7行由于前7行没有发生新的赋值,所以输出function a(){alert(3)} 第八行发生赋值 所以第9行输出2 后面的全是2
另外 函数的优先级比变量大 即便最后第14行之后又有声明 var a=50 这样的,前三个还是会输出function a(){alert(3)}
7 递归函数(回调函数)
自己调用自己的函数
例如 求阶乘
function jiecheng(n){
if(n<2)
{
return 1
}
return n*jiecheng(n-1);
}
var result=jiecheng(10);
alert(result);
然后回调函数是将函数当做参数来使用的函数,这个函数就是回调函数
例如:
function aa(fn){
alert("这是原来的AA方法");
fn();
}
function bb(){
alert("这是回调以后的BB方法");
}
aa(bb);
即 bb函数被当做一个参数放入了aa函数