用几个经常会碰到的变态笔试题弄懂Javascript作用域吧!
1.练习
1 alert(a) 2 var a = 10; 3 alert(a); 4 a(); 5 function a(){ 6 alert(2); 7 }
1.1 以上代码JS是如何解析的呢?
首先,我们要明白Javascript的解析过程有定义阶段和执行阶段,那么我就用我理解的来做这些练习题
分析:
(1) 定义 (var和函数声明)
var a ;
function a() {alert(2);}
在定义阶段就只有这两个,而因为它们的名字相同,所以var a会被忽略,那么就只剩下
function a() {alert(2);},于是在定义阶段只剩下函数声明
(2) 执行
来到执行阶段,OK,那就一步步往下执行好了
alert(a) // 定义阶段有function a() {alert(2)},于是会弹出这个函数体
a = 10; // 这一步是赋值,上一步相当于 var a = function() {alert(2);},这一步改变了a的值
alert(a) // 10
a(); // 这里会报错,a is not function,因为此时a已经赋值为10,那么10()是什么呢?所以会报错
1.2 于是乎,以上这道题的答案就是,首先弹出function a() {alert(2);} ,然后再弹出10.
2.练习
1 alert(a); 2 var a=10; 3 4 alert(a); 5 function a(){ 6 alert(20); 7 } 8 9 alert(a); 10 var a=30; 11 12 alert(a); 13 14 function a(){alert(40);} 15 alert(a);
2.1 上面这道题看上去是不是也会很晕呢?那么JS到底是怎样解析的呢?其实通过上面的分析,很快就会得出答案
分析:(由于上面已经分析得很详细,那么下面的分析思路就省略了)
(1) 定义 (var和函数声明)
var a;
function a(){alert(20);}
var a;
function a(){alert(40);}
最后剩下function a(){alert(40);}
2.执行
第1条语句 alert(a) //function a(){alert(40);}
第2条语句 a = 10 //给a赋值
第3条语句 alert(a) //10
第4条语句是函数声明,是在定义阶段,不是执行阶段
第5条语句 alert(a) //10
第6条语句 a = 30; //赋值
第7条语句 alert(a) //30
第8条语句同第4条语句都是函数定义
第9条语句 alert(a) //30
2.2于是乎,上面的执行结果为function a(){alert(40);},10,10,30,30
3.练习
1 a(); 2 var a = function(){alert(1);} 3 a(); 4 function a(){alert(2);} 5 a(); 6 var a = function b(){alert(3);} 7 a();
3.1分析JS的解析过程
1.定义
function a(){alert(2);}
2.执行
a(); //2;
a = function(){alert(1)}; //赋值
a(); //1
a() // 1;
a = function b(){alert(3)} //赋值
a() //3
3.2 以上执行结果为2,1,1,3
4 练习
1 var a = 0; 2 function fn(){ 3 alert(a); 4 var a = 1; 5 alert(a); 6 } 7 fn();
4.1分析
(1) 定义
var a;
function fn(){alert(a);var a=1;alert(a);}
(2) 执行
fn() //fn()作用域
(1) 定义
var a;
(2) 执行
alert(a) //undefined
a = 1; //赋值
alert(a) //1
4.2 这里就会有全局作用域和局部作用域的考察,在fn()作用域中,当函数执行完成,变量会销毁.结果为undefined,1
5.练习,如果我们将第四道题稍微改定一下,讲fn()函数里声明的变量a,var去掉那会怎样呢?
1 var a = 0; 2 function fn(){ 3 alert(a); 4 a = 1; 5 alert(a); 6 } 7 fn();
5.1 分析
(1) 定义
var a;
function fn(){alert(a);a=1;alert(a)}
(2) 执行
fn() // fn()作用域
(1) 定义
在此作用域未定义
(2) 执行
alert(a) //会往上级作用域查找a,于是弹出0
a = 1 //赋值
alert(a) //1
5.2 结果为0,1
6.练习
1 fn(); 2 alert(a); 3 var a = 0; 4 alert(a); 5 function fn(){ 6 var a = 1; 7 }
6.1 分析
(1) 定义
var a;
function fn(){var a=1;}
(2) 执行
fn() // 什么也不做
alert(a) //undefined
a = 0; //赋值
alert(a) //0
6.2 结果弹出undefined,0
7.练习
1 fn(); 2 var a = 0; 3 function fn() { 4 alert(a); 5 var a = 3; 6 function c() { 7 alert(a); 8 } 9 return c; 10 }
7.1 分析
(1) 定义
var a;
function fn(){alert(a);var a=3;function c(){alert(a)};return c;}
(2) 执行
fn() //fn()作用域
(1) 定义
var a;
function c(){alert(a);}
(2) 执行
alert(a) //undefined
a = 3; //赋值
7.2执行结果:弹出undefined
8.练习
1 var a = 1; 2 function fn(a){ 3 alert(a); 4 a++; 5 alert(a); 6 } 7 fn(a); 8 alert(a);
8.1 分析
(1) 定义
var a;
function fn(a){alert(a);a++;alert(a)}
(2) 执行
a = 1; //赋值
fn(a) //fn()作用域
(1) 定义
var a; //参数
(2) 执行
a = 1; //赋值
alert(a) // 1
a++ ; //2
alert(a) //2
alert(a) //1
8.2 结果为弹出1,2,1
9.练习,对练习8的稍作改动,如果这时候fn函数定义的时候没有参数会怎样呢?请看下面的分析
1 var a = 1; 2 function fn(){ 3 alert(a); 4 a++; 5 alert(a); 6 } 7 fn(a); 8 alert(a);
9.1 分析
(1) 定义
var a;
function fn(){alert(a);a++;alert(a);}
(2) 执行
a = 1; //赋值
fn(a) //fn()作用域
(1) 定义
(2) 执行
alert(a) //因为fn()作用域没有定义变量a,所以会向上查找 ,结果找到了a = 1,于是弹出1
a++ //2
alert(a) //2
alert(a) //此时的a是多少呢?可以看到fn()里弹出的a是全部作用域,而这里即将弹出的a也是全局作用域,所以应该弹出2,而不是1
9.2执行结果为:1,2,2
10 总结
如此通过上述Javascript作用域的详解发现,只要我们清楚在定义阶段有哪些,在执行阶段变量的值,那么对于这样的题目只要仔细分析,就不会太难了吧!!嘿嘿,是不是收获很大呢?