作用域和作用域链
1. 变量的作用域
// 局部变量只在其定义时所在的function内部有意义
function test(){
var a=10;
console.log(a) //10 局部变量可在局部的作用域获取到
}
test();
// 外面获取不到局部的
console.log(a) //报错Uncaught ReferenceError a is not defined
// 特殊的局部变量---形参
var a = 10; // 没有包裹在函数内部的全局变量
function test(a){ // 形参a也是函数内的局部变量
console.log(a); //20 就近拿到局部变量
a++;
console.log(a) // 21 局部变量自增的值
}
test(20);// 20实参
console.log(a); // 10 (函数里面的20是局部的值,全局的还没被修改)
// 全局变量就是不将变量定义在任何函数的内部,它在任何函数内都可以被访问和更改。
var a=10; // 没有包裹在函数内部的全局变量
function test(){
a++; // 获取到全部变量且修改
console.log(a) //11
}
test();
console.log(a) // 获取到修改后的全局变量
// 遮蔽效应(如果函数中也定义了和全局同名的变量,则函数内的变量会将全局的变量“遮蔽”。)
var a=10; // 没有包裹在函数内部的全局变量
function test(){
var a=20; // 局部把全局变量a "遮蔽"了
a++; // 就近修改
console.log(a) // 21 (拿到修改后的值)
}
test();
console.log(a) //10 (函数里面的20是局部的值,全局的还没被修改)
// 变量提升问题 声明变量后 var和变量名会提升到作用域的最前面
var a=10; // 没有包裹在函数内部的全局变量
function test(){
console.log(a)//undefined (局部里有声明变量的话 var a会被提升,但没赋值),
a++; // 前一步变量提升后 a的值undefined,自增
console.log(a) // NaN (上一步undefined的值 自增后的值为)
var a = 20; // 上面提升后值为undefined,现在重新a=20赋值
console.log(a) // 20 (拿到最新值)
}
test();
console.log(a) //10 (函数里面的20是局部的值,全局的还没被修改)
2.作用域和作用域链
作用域(Scope):作用域就是变量或者函数的执行环境或者所作用到的区域
作用域链(Scope Chain):当有函数嵌套时,里层函数的变量在获取值的时候,会从自己当前的作用域开始一层一层向上找,找到全局后就怂管了,这样一层一层的关系就称为作用域链
// 函数的嵌套 作用域是分层的,内层作用域可以访问外层作用域的变量,反之则不行
var a = 10;
function outer(){
console.log(a)//10 全局的大家都能访问
var c=20;
function inner(){
var b=30; //局部的
var c=40;
console.log(a); // 10 全局的大家都能访问
console.log(c)// 40 里层的能访问外层的
}
inner();
console.log(b); //报错 外层的不能访问里层的
}
outer();
以下为整个函数在执行时候,所形成的比较详细的作用域链,主要看执行的时候形成的作用域链,简而言之还是那句话,里面的能拿外面的,外面的不能取到里面的
3. 小试牛刀
function a(){
glob++;
function b(){
var c = 234;
a++;
console.log(a) // ?
}
var a = 123;
b();
console.log(c); // ?
console.log(glob); //?
}
var glob = 100;
a();
function test1(a){
var a=10;
function test2(){
var b=20;
function test3(){
var c=30;
b++;
console.log(a+b+c); //?
}
test3()
console.log(b);//?
console.log(a+b+c)//?
}
test2()
console.log(a,b,c)
}
test1(10)

浙公网安备 33010602011771号