混乱的“变量声明”

简介: 有了问题,就想办法解决,不然留在脑子了是一种负担,当然,可以忘记这些,就当这些从来没发生过,相信很多技术人员在此类问题上会更执着,有的时候脑子中的一个想法,甚至会让其疯狂的将自己身边应有尽有的技术书籍翻个底朝天,目的只有一个,想知道这个问题的答案,有种“不到黄河心不死”想法,一定要将问题弄得清清楚楚,明明白白。

    有了问题,就想办法解决,不然留在脑子了是一种负担,当然,可以忘记这些,就当这些从来没发生过,相信很多技术人员在此类问题上会更执着,有的时候脑子中的一个想法,甚至会让其疯狂的将自己身边应有尽有的技术书籍翻个底朝天,目的只有一个,想知道这个问题的答案,有种“不到黄河心不死”想法,一定要将问题弄得清清楚楚,明明白白。

   对于开源世界,我是很想投入,也很想去做一些自己能做的事情,可惜只怪自己学术不精,往往进去都是找一个跟自己相关的东西,而从来没有什么贡献。不知道什么时候有了从源码中找答案的这个想法,前面的博客中说过,程序中的问题,可以通过调试,跟踪,模拟等手段找原因,其实还可以从源码中获取相关答案,请相信:源码中可以找到问题的本质的。

   对于<<深入浅出MFC>>这本书,作者就是通过自己去模拟MFC的过程,也通过提示,让我们去看MFC的源码,我很喜欢这本书,尽管这本书我花了好长好长的时间才看完,但是我喜欢这本书最根本的是:提供了我们解决问题的方法。一本好书,不仅仅给人一鱼,更重要的是给人一渔。

现在言归正传,回到这博文的主题上,为什么又是一个”混乱“?前面不是已经有了一篇了么?

在我们C#,Java这样的面向对象语言中,变量的作用域是很关键的,不仅仅是这些面向对象的语言,其实所有的语言都一样吧?今天我不谈变量的类型,也不谈变量的private,public等访问,就谈谈作用域。C#,Java变量按照作用范围大体上分为属于类的,也就是用static声明的,然后就是成员变量以及方法变量,成员变量是整个对象都可以访问的,而方法变量是只有该方法可以访问。

那么javascript呢?如果看了JQuery的源码,可以看到JQuery的所有东西都在一个自执行的匿名函数中,在这个匿名函数中传递了一个windows全局对象,而在这个windows对象中附加上了JQuery和$这两个,这两个也就是我们访问JQuery的入口。

但是清楚的话可以看到源码一开始就有一个Var JQuery,而给windows附加的JQuery对象是在最后,一个Var,一个没有用Var,而是直接加在了wndows之后作为全局变量。这个其实就是Javascript的变量范围,也就是全局变量和局部变量,因为JQuery在我的心中根本就不是面向对象的语言,没有类,接口,继承等,但是它都可以模拟出来,我真是不懂。

下面是我找的一篇帖子,里面对变量的声明做了介绍,文章来自:http://www.cnblogs.com/snandy/archive/2011/03/19/1988284.html

变量变量声明是一门语言最基本的概念,初学者都会很快掌握。JavaScript中声明变量也是如此,很简单var(关键字)+变量名(标识符)。

方式1

?
1
2
var test;
var test = 5;

需注意的是该句不能包含在function内,否则是局部变量。这是第一种方式声明全局变量。

 

方式2

?
1
test = 5;

没有使用var,直接给标识符test赋值,这样会隐式的声明了全局变量test。即使该语句是在一个function内,当该function被执行后test变成了全局变量。

 

方式3

?
1
2
window.test;
window.test = 5;

这种方式经常被用到一个匿名函数执行后将一些函数公开到全局。 如JQuery1.5中最末一句

?
1
window.jQuery = window.$ = jQuery;

 

如果只是使用变量test,那么三种方式将没有什么区别。比如:alert(test) 都将显示5。但三种方式在某些情况下还是有区别的。分别按以上三种方式声明三个变量a1,a2,a3。

?
1
2
3
a1 = 11;
var a2 = 22;
window.a3 = 33;

 

1,for in window

?
1
2
3
4
5
for (a in window){
     if (a== 'a1' ||a== 'a2' ||a== 'a3' ){
         alert(a)
     }
}

IE6/7/8/9:只弹出了a3,说明通过第一,二种方式声明的全局变量通过for in window时将获取不到。
Firefox/Chrome/Safari/Opera :a1,a2,a3都弹出了,说明三种方式声明的全局变量,通过for in window时都能获取到。

 

2,delete

?
1
2
3
4
5
6
7
8
9
10
11
try {
     alert( delete a1);
} catch (e){alert( '无法delete a1' )}
  
try {
     alert( delete a2);
} catch (e){alert( '无法delete a2' )}
  
try {
     alert( delete a3);
} catch (e){alert( '无法delete a3' )}

结果如下

可以看到,
1,delete a2所有浏览器都是false。即通过var声明的变量无法删除,所有浏览器表现一致。这在犀牛书上也有提到。
2,通过window.a3方式声明的全局变量在IE6/7/8中均无法删除,IE9/Firefox/Chrome/Safari/Opera中却可以。


虽然有以上两点不同,但当用in运算时,都返回true。

?
1
2
3
alert( 'a1' in window); //true
alert( 'a2' in window); //true
alert( 'a3' in window); //true

用with打开对象window闭包时,所有浏览器也表现一致,如下

?
1
2
3
4
5
6
7
8
9
10
11
with (window){
     if (a1){
         alert(a1); //11
     }
     if (a2){
         alert(a2); //22
     }
     if (a3){
         alert(a3); //33
     }   
}

 

相关:

 

 

相关文章
|
7月前
|
C++
全局变量初始化顺序探究
全局变量初始化顺序探究
|
2月前
好的编程习惯
好的编程习惯
35 0
|
4月前
this的含义,什么情况下使用this,改变this指针的两种办法。 === 由于this关键字很混乱,如何解决这个问题
this的含义,什么情况下使用this,改变this指针的两种办法。 === 由于this关键字很混乱,如何解决这个问题
18 0
|
4月前
|
JavaScript 前端开发
JavaScript开发基础问题:解释一下变量提升。
JavaScript开发基础问题:解释一下变量提升。
41 5
什么是闭包?闭包的用途是什么?闭包的缺点是什么?
变量的作用域有两种:全局变量和局部变量; 函数内部可以直接读取全局变量; 在函数外部无法读取函数内的局部变量。 能够读取其他函数内部变量的函数,就是闭包
86 0
|
自然语言处理 程序员
《代码大全》中的变量
《代码大全》中的变量
《代码大全》中的变量
|
JavaScript 前端开发
0308-变量声明提前
变量会先声明后赋值 test(); function test() { console.
740 0
|
C语言 C++
c语言几个松散的地方(不足的地方,不严谨的地方,它容易出错的地方)。
c语言是面向过程的语言,是弱类型语言,c语言的源代码基本就是无数个函数的堆砌。即很多函数就组成c语言源代码了,也即它的源代码基本就是函数构成的。 C语言里面的test()和test(void)是不一样的。
956 0
|
缓存 JavaScript