[100 分,100分,100分] javascript中全局变量,突然不全局了,是学习时发现的,请高人给讲一下,明白后立即结贴
[100 分,100分,100分] javascript中全局变量,突然不全局了,是学习时发现的,请高人给讲一下,明白后立即结贴
JScript code<html><head><script language="javascript" type="text/javascript"><!--var00 = 0;document.write(var00 + '<br>');var01 = 1;//A:全局变量是吧function foo(){ document.write(var01); //B:是调用A处的全局变量吧,为什么最后的输出结果是‘undefined’呢??? var var01 = 1;}foo();--></script></head><body></body></html>
我读了《js局部变量/全局变量》一文,地址如下
http://www.cnblogs.com/simhare/archive/2007/08/25/869440.html
文中说“在js中如果用var来定义一个变量,如果该变量被定义在function或者其他循环体内,则变量为局部变量,并且该变量不会受到同名全局变量的影响,也不会影响同名的全局变量。如果不用var来定义变量而直接拿一个变量来使用则该变量会被自己定义为全局变量,无论该变量被定义在任何位置,如果在function或者循环体内用这种方式来定义变量,则该变量为全局变量若function或循环体外已经定义了同名的全局变量,则会直接引用function或循环体外定义的全局变量。”
可是事实,却不一样??B处根本没有引用A处的全局变量啊??为什么??请高人给讲一下,明白了立即给分,谢谢看贴子的朋友,本贴不散分
[解决办法]具体什么原因我也说不出,不过我说下我的想法,因为一般开发不可能写出这样的代码,不过竟然发现了,我们就解决下
首先
function foo()
{
document.write(var01); //B:是调用A处的全局变量吧,为什么最后的输出结果是‘undefined’呢???
var var01 = 1;
}
foo();
这里可能是由于javascript解释的时候,先把变量做处理,然后再对函数做处理,所以导致这种情况
怎么说比较清楚呢。。。。也就是说当javascript运行的时候,javascript解释器会先对全局变量做处理,然后是函数内的局部变量,然后是函数内语句做处理,比如保存在内存的某的地方,当你调用foo()的时候,其实是直接调用指针函数,这样说来,解释器 把由于后面foo里有var var01 和上面的变量一样,所以把全局变量给覆盖了,所以导致了这种情况,也就是说,他不把var01当全局变量看。
function foo()
{
document.write(var01); //B:是调用A处的全局变量吧,为什么最后的输出结果是‘undefined’呢???
//var var01 = 1;//我把这句给隐去了,结果输出为“1”,也就是说B处引用到了A处全局变量的值,晕了,为什么加上var var01 = 1;就引用不到呢?
}
这里去掉后,就变成正常的写法了,没有var01的影响,所以就正常了
function foo()
{
document.write(var01); //B:是调用A处的全局变量吧,为什么最后的输出结果是‘undefined’呢???
var01 = 111;//这里把var var01改成了 var01,结果B处输出为“1”,并且全局变量最终结果是“111”,天啊,到底是为什么啊
}
这里的var01并没有重新生成变量,所以相当于修改全局变量而已,当然也是正确的
[解决办法]我先声明,我对javascript始终是处于初学,厌学阶段{我非常不喜欢它},所以,只是乱说一下。
《js局部变量/全局变量》一文中给了一个误导的概念。是的,javascript变量是分为全局和局部,但绝对不是因为用没用“var”来声明变量。
我比较认同“在任何函数定义之外声明了一个变量,则该变量为全局变量,且该变量的值在整个持续范围内都可以访问和修改。如果在函数定义内声明了一个变量,则该变量为局部变量。每次执行该函数时都会创建和破坏该变量;且它不能被该函数外的任何事物访问。一个局部变量的名称可以与某个全局变量的名称相同,但这是完全不同和独立的两个变量。因此,更改一个变量的值不会影响另一个变量的值。在声明局部变量的函数内,只有该局部变量有意义。”,也就是说Var也可能声明全局变量的,当然隐式声名变量总是被创建为全局变量。
对于上面出现的几种效果,我也说不太明白,但“所以把全局变量给覆盖了”这种说法,我绝对不认同,“一个局部变量的名称可以与某个全局变量的名称相同,但这是完全不同和独立的两个变量。因此,更改一个变量的值不会影响另一个变量的值。在声明局部变量的函数内,只有该局部变量有意义。”,这句话,我是认为绝对是对的,所以我不同意“所以把全局变量给覆盖了”这种说法。
顺便说说,认真是好事,但应该按着套路来,js一般都是在前面定义变量等成员的,所以没有出现你说的麻烦事~~~
[解决办法]就你的例子来进行说明:
1,JavaScript 的变量范围问题
JavaScript 有两种变量范围:全局和局部。如果在任何函数定义之外声明了一个变量,则该变量为全局变量,且该变量的值在整个持续范围内都可以访问和修改。如果在函数定义内声明了一个变量,则该变量为局部变量。每次执行该函数时都会创建和破坏该变量;且它不能被该函数外的任何事物访问。这一点没有任何问题,大家的理解都不会出现问题。
2,一个局部变量的名称可以与某个全局变量的名称相同,但这是完全不同和独立的两个变量。因此,更改一个变量的值不会影响另一个变量的值。在声明局部变量的函数内,只有该局部变量有意义。你的问题就是出现在这个地方。在你的函数foo()里又进行了定义 var var01 = 1; 这才是你出现问题的原因所在。JavaScript 不是按顺序执行的吗?以上代码为什么会出错?这是一个很令人迷惑的地方,也是从你的例子执行结果为undefined 而百思不得其解的原因。请继续看下面的一条规则。
3,当 JavaScript 运行函数时,首先查找所有的变量声明,并以未定义的初始值创建变量。如果变量被声明时有值,那么该变量仍以未定义的值初始化,并且只有在运行了声明行时才被声明值取代,假如曾经被声明过。也就是说,你在foo()里又定义了一次 var var01 = 1;,此时,var01 被看作是局部变量了,和外面的var01已经不是同一个变量了。所以,document.write(var01) 的结果首先要肯定不是外面的 1。好,就算是局部变量,我在foo()里已经赋值为 1 了,为什么结果还是 undefined ?仔细看一下本段前面的说明,“首先查找所有的变量声明,并以未定义的初始值创建变量”,即使你在foo()里进行了var01赋值,但 JavaScript 代码执行时,知道了你定义了变量(因为此时没有报“变量未定义”错误),但没有执行到赋值语句时,是没有值的,所以才出现 undefined 的结果。
4,JavaScript变量声明:变量在脚本中的第一次出现是在声明中。变量在第一次用到时就设置于内存中,便于后来在脚本中引用。使用变量之前先进行声明。可以使用 var 关键字来进行变量声明。如果在 var 语句中没有初始化变量,变量自动取 JScript 值 undefined。尽管并不安全,但声明语句中忽略 var 关键字是合法的 JScript 语法。这时,JScript 解释器给予变量全局范围的可见度。如果变量是在函数中显式声明的 — 也就是说,如果它出现于赋值表达式的左边但没有用 var 声明 — 那么将把它创建为全局变量。下面例子中的 var03 就是证明。
JScript code<html><head><script type="text/javascript"><!--var00 = 0;document.write(var00 + '<br>');var01 = 1;//A:全局变量是吧function foo(){ document.write(var01 + '<br>'); //B:是调用A处的全局变量吧,为什么最后的输出结果是‘undefined’呢??? var var01 = 2; var03=3; var var04 = 4}foo();document.write(var01 + '<br>')document.write(var03 + '<br>')document.write(var04 + '<br>')--></script></head><body></body></html>
[解决办法]
HTML code 发表于:2007-11-07 21:32:45 楼主 JScript code<html><head><script language="javascript" type="text/javascript"><!--var00 = 0;document.write(var00 + '<br>');var01 = 1;//A:全局变量是吧function foo(){ document.write(var01); //B:是调用A处的全局变量吧,为什么最后的输出结果是‘undefined’呢??? var var01 = 1;}foo();--></script></head><body></body></html>/*简单点说。。javascript开始执行前,它会解释所有已声明的变里,,顺序如下:1. var00 -->已声明2. var01 --> 已声明 --->关键所在。3. 函数内部var var01=1; --->所有这里已声明。。可以把这个看成两步var var01 ;var01=1; 先会执行var var01;但发现 发现第2步( 指全局var01) 已经声明。所以会在其内部把全局变量隐藏掉了。但此里又没有附值给var01附值会在 document.write(var01); 执行后,执行。。*/
[解决办法]
我在这里给出简单的解释:
什么是域?就是scope,我们平常所说的变量作用域,不过通常直接叫做域。在JavaScript当中,只有function是域的分界,如果那篇文章告诉你循环也能作为域的分界,那就是错误的。
那么域只能有一层?错,JavaScript里面function能够套function,例如:
var v;
function myObject() {
var v;
this.myMethod = function() {
var v;
alert(v);
}
}
关于变量的引用,从最内层域开始向外搜索,直到找到同名定义为止,如果到了全局域都找不到定义,变量就是未定义。例如alert(v)里面的v,就是最内层的var v。如果这个var v去掉,就是中间层的var v。如果也去掉,就是最外层的var v。