在博客上看到一篇文章,感觉很有意思,认真看完了全文,文章确实不错,也加深了我对JavaScript变量的一个理解,所以打算借鉴一下,写了一个自己的学习总结,整理出了这篇读后感。
文章原始出处:http://apps.hi.baidu.com/share/detail/50528730
博主阅读地址:http://blog.csdn.net/zyz511919766/article/details/7276089
事件的起因是两段代码,比较两段代码的区别:
<script type="text/javascript">
var a = "Hello";
function test(){
var a;
alert(a);
a = "World";
alert(a);
}
</script>
<script type="text/javascript">
var a = "Hello";
function test(){
alert(a);
a = "World";
alert(a);
}
</script>
其实也很简单,就是比较JavaScript中的全局变量和局部变量,刚开始看代码的时候我还没有去看原博主的文字,只是在思考两段代码的区别和运行结果,这两段的答案大家都知道,第一段代码为是:undefined,world;第二段代码输出:hello,world。
从原博客上看,这个问题还是一个妹纸问的,既然知道区别,又知道答案,理所当然,当然理所原博主肯定会怒装一*咯,是吧!换做是我我也会,不然天理难容!然后只看原博主以瞬雷不及掩耳盗铃响叮当之势写出了一个example给妹纸进行讲解,example如下:
<script>
var a =1;
function test(){
alert(a);
var a = 2;
alert(a);
}
test();
alert(a);
</script>
这个例子很简单对吧,按照我们“正常”的理解以及Java编程的思维,结果就是1,2,1。第一次输出取的是全局变量,第二次输出取的是局部变量,第三次又回到了全局变量。如果你也是这么认为的话,我会告诉你:nice,没瑕疵!因为我也是这么认为的,原博主也是这么认为的!
然而,当妹纸拿到example后,测试结果一出来,……估计当时博主心中无数只马在策马奔腾!虽然原博客给出了测试结果,但我不会告诉你,请自行测试!博客只看不动手是没有任何效果的,必须要亲自测试一次你才能感受到那千万只马奔腾的感觉!骚年,动下手指头去测测,你会知道什么叫酸爽和懵逼!
在开发的“萌”妹纸面前装B失败,小脸被打得啪啪啪的响,作为男人怎能不挽回点颜面,是吧!所以呢原博主就痛定思痛,进行了系列的学习+测试写下了这篇博客(我也只是猜测如此),接下来我会把原博客中的例子先全部照搬过来,然后再在最后写出我自己的一些学习心得,大家可以进行比较学习,这样印象更加深刻!
—————————以下就是原博客的总结示例—————————
一、Javascript的变量的scope是根据方法块来划分的(也就是说以function的一对大括号{ }来划分)。切记,是function块,而for、while、if块并不是作用域的划分标准,可以看看以下几个例子:
<script>
function test2(){
alert ("before for scope:"+i); // i未赋值(并不是未声明!使用未声明的变量或函数全抛出致命错误而中断脚本执行)
// 此时i的值是underfined
for(var i=0;i<3;i++){
alert("in for scope:"+i); // i的值是 0、1、2, 当i为3时跳出循环
}
alert("after for scope:"+i); // i的值是3,注意,此时已经在for scope以外,但i的值仍然保留为3
while(true){
var j = 1;
break;
}
alert(j); // j的值是1,注意,此时已经在while scope以外,但j的值仍然保留为1
if(true){
var k = 1;
}
alert(k); //k的值是1,注意,此时已经在if scope以外,但k的值仍然保留为1
}
test2();
//若在此时(function scope之外)再输出只存在于test2 这个function scope里的 i、j、k变量会发生神马效果呢?
alert(i); //error! 没错,是error,原因是变量i未声明(并不是未赋值,区分test2函数的第一行输出),导致脚本错误,程序到此结束!
alert("这行打印还会输出吗?"); //未执行
alert(j); //未执行
alert(k); //未执行
</script>
二、Javascript在执行前会对整个脚本文件的声明部分做完整分析(包括局部变量),从而确定实变量的作用域。怎么理解呢?看下面一个例子:
<script>
var a =1;
function test(){
alert(a); //a为undefined! 这个a并不是全局变量,这是因为在function scope里已经声明了(函数体倒数第4行)一个重名的局部变量,
//所以全局变量a被覆盖了,这说明了Javascript在执行前会对整个脚本文件的定义部分做完整分析,所以在函数test()执行前,
//函数体中的变量a就被指向内部的局部变量.而不是指向外部的全局变量. 但这时a只有声明,还没赋值,所以输出undefined。
a=4
alert(a); //a为4,没悬念了吧? 这里的a还是局部变量哦!
var a; //局部变量a在这行声明
alert(a); //a还是为4,这是因为之前已把4赋给a了
}
test();
alert(a); //a为1,这里并不在function scope内,a的值为全局变量的值
</script>
三,当全局变量跟局部变量重名时,局部变量的scope会覆盖掉全局变量的scope,当离开局部变量的scope后,又重回到全局变量的scope,而当全局变量遇上局部变量时,怎样使用全局变量呢?用window.globalVariableName。
<script>
var a =1;
function test(){
alert(window.a); //a为1,这里的a是全局变量哦!
var a=2; //局部变量a在这行定义
alert(a); //a为2,这里的a是局部变量哦!
}
test();
alert(a); //a为1,这里并不在function scope内,a的值为全局变量的值
</script>
—————————以上就是原博客的总结示例
—————————
—————————以下是个人学习总结—————————
第一个示例很简单,我也不再写其他示例。
1、第二个示例的学习比较
原示例:原示例中说第一个输出undefined是因为在后面有对a进行申明
<script>
var a =1;
function test(){
alert(a);
a=4
alert(a);
var a ;
alert(a);
}
test();
alert(a);
</script>
<script>
var a =1;
function test(){
alert(a);
a=4
alert(a);
}
test();
alert(a);
</script>
结论:除去a局部变量变量的申明,整个示例中使用的就是全局变量a,故证明了注释中的那点事正确的!
变形2:如果在申明a局部变量的同时给局部变量a赋值,第一次输出局部变量时会不会输出初始值?
<script>
var a =1;
function test(){
alert(a);
a=4
alert(a);
var a =5;
alert(a);
}
test();
alert(a);
</script>
结论:虽然第一次取出的a是局部变量的a,但是输出还是undefined,因为虽然a在申明时被赋了值,但是在前面依然还是取不到该值,var a = 5;相当于var a; a= 5; 只有在执行到了a = 5时才能取到值。
2、第三个示例我觉得这样写的话比较会更为明显
<script>
var a =1;
function test(){
alert(window.a); //a为1,这里的a是全局变量哦!
alert(a); //局部变量
var a=2; //局部变量a在这行定义
alert(window.a); //取全局变量
alert(a); //a为2,这里的a是局部变量哦!
}
test();
alert(a); //a为1,这里并不在function scope内,a的值为全局变量的值
</script>