JavaScript作用域涉及到作用域链等等,这里做个小结。
(1)变量提升:可以理解为把变量提升到当前执行环境的最顶端;
(2)作用域链:当所需要的变量,在所在的作用域中查找不到的时候,它会一层一层向上查找,直到全局作用域还没有找到的时候,就会放弃查找。这样一层一层的关系,就是作用域链。
这里实现了8个例子,每个例子注释那里有详细解析,以飨读者。
<!DOCTYPE html>
<html>
<head lang="en">
<meta http-equiv="Content-Type" charset="utf-8"/>
<title>JavaScript中的作用域</title>
</head>
<script>
//例子01
var a = 10;
(function(){
console.log(a); //undefined
a = 5;
console.log(window.a); //10
var a = 20; //由于这个地方定义了局部变量a,由于js的变量声明提升机制,局部变量a的声明会被提升至立即执行函数的函数体最上方,且由于这样的提升并不包括赋值,所以第一条语句会打印出undedined
console.log(a) //20
})()
console.log('---例子01---')
//例子02
var c = 10;
(function(){
console.log(c); //10--作用域链
c = 5;
console.log(window.c); //5
console.log(c) //5
})()
console.log(c) //5
console.log('---例子02--01-')
var c2 = 10;
function funct(){
console.log(c2); //10
c2 = 5;
console.log(window.c2); //5
console.log(c2) //5
}
funct();
console.log(c2); //5
console.log('---例子02--02-')
//例子03
var b = 123;
(function(){
console.log(b); //123
b = 456;
}());
console.log(b); //456
console.log('---例子03---')
//例子04--要跟例子02区分开来
var d=1;
function fn1(d){
console.log(d); //undefined --这个地方由于方法fn1()没有传值过来,所以d找的作用域是方法fn1(d)里面,不会找外面的,所以输出值为undefined
d=2;
console.log(d); //2
};
fn1();
console.log(d); //1
console.log('---例子04---')
//例子05
var e=1;
function fn1(){
console.log(e); //1 --调用全局作用域中的e
e=2;
console.log(e); //2
};
fn1();
console.log(e); //2
console.log('---例子05---')
//例子06
function test(){
console.log(p); //undefined
console.log(foo()); //依次输出:undefined 2
console.log(p); //输出undefined
var p=1;
function foo(){
console.log(p); //undefined--因为变量作用域链的理解,在所在的作用域中查找不到的时候,它会一层一层向上查找,直到全局作用域还没有找到的时候,就会放弃查找。
return 2; //2
}
}
test()
console.log('---例子06---')
//例子07
var k=1;
function check(){
return function(){
console.log(k); //1
console.log(j); //Uncaught ReferenceError:j is not defined
}
}
var func=check();
func();
console.log('---例子07---')
</script>
<body>
<button onclick="">弹框</button>
</body>
</html>