这应该是最全的闭包题目了吧~
1.外层的变量,内层可以找到(全局),内层的变量,外层找不到(局部)
<script>
//1.外层的变量,内层可以找到(全局),内层的变量,外层找不到(局部)
/*function aaa(){
var a = 10;
console.log(a);//10
}
aaa();
console.log(a);// 直接报错,a is not defined*/
var a = 10;
function aaa(){
console.log(a);//10 这里是找外层的,bbb里面的a在这里相当于内层,并不会进去找
}
function bbb(){
var a = 20;
aaa();
}
bbb();
</script>
2.当var不加的时候,会自动生成全局的变量(不建议这样写,最好把所有要定义的变量加上var)
<script>
//2.当var不加的时候,会自动生成全局的变量(不建议这样写,最好把所有要定义的变量加上var)
/*function aaa(){
a = 10;
}
aaa();
console.log(a); //10*/
/*function aaa(){
var a = 10;
}
aaa();
console.log(a); //报错,a is not defined 注意和上面的区别*/
function aaa(){
var a = b = 10;
}
aaa();
// console.log(a); //直接报错,a is not defined 为什么? 应该是var a=b=10,相当于 var a= 10, b=10, b没有var,所以正确
console.log(b); //10
</script>
3.变量的查找是就近原则去需找,var定义的变量,当就近没有找到的话,就会查找外层
<script>
//3.变量的查找是就近原则去寻找,var定义的变量,当就近没有找到的话,就会查找外层
/*var a = 10;
function aaa(){
console.log(a); //undefined 内部有声明,预解析 var a提前变到14行之前,注意undefined和报错的区别啊,1报错是连声明都没有,undefined是有了声明只是没赋值而已
var a = 20;
}
aaa();
*/
/*var a = 10;
function aaa(){
var a = 20;
console.log(a); //20 在里面直接有,又在前面,肯定就近啊
}
aaa();*/
/*var a = 10;
function aaa(){
console.log(a); //10 这里是去外面找去了,因为里面没有var就会去外面找,下面一句a=20要不要都是10
a = 20;
}
aaa();
*/
/*var a = 10;
function aaa(){
console.log(a); //undefined 有var声明提前
var a = 20;
//相当于下面:
//var a;
//console.log(a); //undefined 预解析
//a = 20;
}
aaa();
*/
/*var a = 10;
function aaa(){
bbb();
console.log(a); //10 先在自己的里面找,没有找到var, a只会去外面找,不会进入内层作用域的
function bbb(){
var a = 20;
}
}
aaa();*/
var a = 10;
function aaa(){
bbb();
console.log(a); //undefined 先在自己的里面找,找到了var,预解析,提前,反正都不进内层作用域
var a =30 ;
function bbb(){
var a = 20;
}
}
aaa();
</script>
4.当参数跟局部变量重名的时候,优先级是等同
<script>
//4.当参数跟局部变量重名的时候,优先级是等同
/*var a = 10;
function aaa(a){
console.log(a); //10
var a = 20;
}
aaa(a);*/
/*var a = 5;
var b = a;
b += 3;
console.log(a); //5 */
/*var a = [1,2,3];
var b = a;
b.push(4);
console.log(a); //[1,2,3,4] 这一题画内存图,因为数组是存在堆中的,此题是把a赋值给b,即a在内存中的栈地址也就是b的,它们都共同指向同一堆中,所有b的堆内容变化,则a也变化 */
/*var a = [1,2,3];
var b = a;
b = [1,2,3,4];
console.log(a); //[1,2,3] 这一题是b重新建了一个数组,即重新指向了新的堆内存,所有b变,a不受影响
*/
/*var a = 10;
function aaa(a){
a += 3;
console.log(a) //13
}
aaa(a);
console.log(a); //10 这是在作用域外面不受影响 不会进入内层的*/
/*var a = [1,2,3];
function aaa(a){
a.push(4);
}
aaa(a);
console.log(a);//[1,2,3,4] 这应该也可以用上面的堆内存解释,直接对a push后,改变了a的值*/
var a = [1,2,3];
function aaa(a){
a = [1,2,3,4];
}
aaa(a);
console.log(a); //[1,2,3] 这也没有改堆内存,而是新建了一个堆内存,所以不行的,不会改变外面a的值
</script>
上述每一项我都验证过,答案正确,下次忘记闭包的时候,再来看看吧。