一、作用域
1. 定义
一个标识符(function , var,形参)可以在哪些地方使用,哪里就是它的作用域。一般情况下,作用域只有在分析函数时才有意义。
2. 访问函数
函数外部的变量/函数,函数外部也可以访问;函数内部的变量/函数,只能在函数内部访问。
var a=111 // 全局变量
console.log(a+100) //打印211,函数外面可以使用a
function fn () {
console.log(a-90)//打印21,函数里面可以使用a
var b=200
console.log(b)//打印200,函数里面可以使用b
}
fn();
console.log(b)//报错,函数外面不可以使用函数里面的b
函数每调用一次,就生成一个新的作用域。函数运行时,无论在哪个作用域调用,都去它生成的作用域跑代码。上面案例中的fn()虽然是在全局作用域里面调用的,但是生成的作用域确是在fn函数体内,b只在fn函数体生成的作用域内声明和使用,所以全局打印b时程序报错了。
函数有形参且调用时,即fn(n),n必须先取值,再传入。例如:fn(n+100)运行时,先运算n+100,再调用函数。
3. 函数运行过程分析
函数运行顺序(js语法中的函数预编译):形/局>实>函>运
1. 形参和局部变量先声明;
2. 把实参传入然后赋值给形参变量;
3. 函数提升;
4. 运行代码
变量和函数的声明提升:函数运行时,会先把函数内部所有的关键字扫描,var修饰的变量名先声明,值为undefined,当代码运行到该变量时,才赋值。函数function也是一样的。
案例:
function fun(n, o) {
console.log(o);
return {
fun: function (m) {
return fun(m, n);
},
};
}
var b = fun(0).fun(1).fun(2).fun(3);
//分析过程
/*
[
function fun
var b=fun(0)==>
[
var n=0, o
console.log(o);//undefined
return { fun: function (m) { return fun(m, n); }}
fun(0).fun(1)==>
[
var m=1;
return fun(m, n)=>fun(1,0)=>1:
fun(0).fun(1).fun(2)==>
[
var m=2;
return fun(m, n)=>fun(2,1)=>2:
fun(0).fun(1).fun(2).fun(3)==>
[
var m=3;
return fun(m, n)=>fun(3,2)=>3:
]
]
]
]
1:[
var n=1, o=0
console.log(o);//0
return { fun: function (m) { return fun(m, n); }}
]
2:[
var n=2, o=1
console.log(o);//1
return { fun: function (m) { return fun(m, n); }}
]
3:[
var n=3, o=2
console.log(o);//2
return { fun: function (m) { return fun(m, n); }}
]
]
*/
注释说明:[ ]表示作用域,1:/2:/3:分别表示三个fun(m,n)的运行过程。