js变量作用域及可访问性的探讨

js|变量|访问

每一种语言都有变量的概念,变量是用来存储信息的一个元素。比如下面这个函数:

 1function Student(name,age,from)
 2{
 3 this.name = name;
 4 this.age = age;
 5 this.from = from;
 6 this.ToString = function()
 7 {
 8  return "my information is name: "+this.name+",age : "+this.age+", from :" +this.from;
 9 }
10}
   Student类有三个变量,分别为name(名字),age(年龄),from(籍贯),这三个变量构成了描述一个对象的信息。当然,这里还有一个方法用来返回Student的信息。
   但是,我们是不是定义了一个变量,它就能一直存在着,并且还有可能在任何地方都能被访问和使用直到其被销毁?仔细想想,上面的需求是比较过分的,因为某些变量在某个功能实现后就不再利用了,但如果这个变量还存在的话,就占用了系统资源了,俗语曰:“站着茅坑不拉#$%”。
   于是我们对变量的及时和按需求地销毁有一个探讨的话题了。
   好,切入正题吧,就本人所接触过的来讲,js中支持如下几种类型的变量,分别为:局部变量、类变量、私有变量、实例变量、静态变量和全局变量。接下来我们就一一探讨研究下。

局部变量:

局部变量一般指在{}范围内有效变量,也就是语句块内有效的变量,如:

 1function foo(flag)
 2{
 3 var sum = 0;
 4 if(flag == true)
 5 {
 6  var index;
 7  for(index=0;index<10;index++)
 8  {
 9   sum +=index;
10  }
11 }
12 document.write("index is :"+index+"<br>");
13 return sum;
14}
15//document.write("sum is :" +sum+"<br>");
16document.write("result is :"+foo(true)+"<br>");
   该代码执行后输出的结果为:“index is :undefined” 和 “result is :0”,我们可以看到希望输出的index变量的值为undefined,也就是未定义。因此我们可以发现,index变量在if语句块结束后即被销毁了。那么“sum”变量呢?这个变量在foo()函数段执行完毕后被销毁了,如果您去掉我注释的那条语句,再执行,您将会发现系统将报错。值得注意的是,如果我把上面的foo()函数改成如下:

 1function foo(flag)
 2{
 3 var sum = 0;
 4 for(var index=0;index<10;index++)
 5 {
 6  sum +=index;
 7 }
 8 document.write("index is :"+index+"<br>");
 9 return sum;
10}

   您将可以看见可以输出index值("index is :10"),这个是js和其他语言的不同地方,因为index是在for循环的{}外面定义的,因此其作用范围在foo()函数使用完毕后才销毁。

  类变量:
   类变量,实际上就是类的一个属性或字段或一个方法,该变量在该类的一个实例对象被销毁后自动销毁,比如我们开始时举的Student类。这个我们不多讨论,大家可以自己试一下。

私有变量:
   私有变量,值得是某个类自己内部是用的一个属性,外部无法调用,其定义是用 var 来声明的。注意如果不用var 来声明,该变量将是全局变量(我们下面将会讨论),如:

 1function Student(name,age,from)
 2{
 3
 4 this.name = FormatIt(name);
 5 this.age = age;
 6 this.from = from;
 7 var origName = name;
 8 var FormatIt = function(name)
 9 {
10  return name.substr(0,5);
11 }
12 this.ToString = function()
13 {
14  return "my information is name: "+origName+",age : "+this.age+", from :" +this.from;
15 }
16}
17
18
   这里,我们分别定义了一个origName和FormatIt()两个私有变量(按面向对象的解释,应该用类的属性来称呼)。
   我们把这种情况下的方法也成为变量,因为该情况下的变量是个function类型的变量,而function也属于Object类的继承类。在这种情形下,如果我们定义了 var zfp = new Student("3zfp",100,"ShenZhen")。但无法通过zfp.origName和zfp.FormatIt()方式来访问这两个变量的。

注意以下几点:

1、私有变量是不能用this来指示的。
2、私有方法类型的变量的调用必须是在该方法声明后。如我们将Student类改造如下:

 1function Student(name,age,from)
 2{
 3 var origName = name;
 4 this.name = FormatName(name);
 5 this.age = age;
 6 this.from = from;
 7 var FormatName = function(name)
 8 {
 9  return name+".china";
10 }
11 this.ToString = function()
12 {
13  return "my information is name: "+origName+",age : "+this.age+", from :" +this.from;
14 }
15}
16var zfp = new Student("3zfp",100,"ShenZhen");
代码执行后,将会报"找不到对象"的错误.意思是FormatName()未定义。

3、私有方法无法访问this指示的变量(公开变量),如下:

 1
 2function Student(basicinfo)
 3{
 4 this.basicInfo = basicinfo;
 5
 6 var FormatInfo = function()
 7 {
 8  this.basicInfo.name = this.basicInfo.name+".china";
 9 }
10 FormatInfo();
11
12}
13function BasicInfo(name,age,from)
14{
15 this.name = name;
16 this.age = age;
17 this.from = from;
18}
19var zfp = new Student(new BasicInfo("3zfp",100,"ShenZhen"));
20
21
执行代码后,系统将会提示 “this.basicInfo为空或不是对象”的错误。
基本结论是,私有方法只能访问私有属性,私有属性在声明并赋值后可以在类的任何地方访问,

实例变量:
实例变量即某个实例对象所拥有的变量。如:

 1
 2function BasicInfo(name,age,from)
 3{
 4 this.name = name;
 5 this.age = age;
 6 this.from = from;
 7}
 8var basicA = new BasicInfo("3zfp",100,"ShenZhen");
 9basicA.generalInfo = "is 3zfp owned object";
10document.write("basicA's generalInfo is : "+ basicA.generalInfo+"<br>");
11var basicB = new BasicInfo("zfp",100,"ShenZhen");
12document.write("basicB's generalInfo is : "+ basicB.generalInfo+"<br>");
13执行该代码后,我们将可以看到如下结果:
14basicA's generalInfo is : is 3zfp owned object
15basicB's generalInfo is : undefined
16
静态变量:

静态变量即为某个类所拥有的属性,通过 类名+"."+静态变量名 的方式访问该属性。如下可以做清晰的解释:

 1function BasicInfo(name,age,from)
 2{
 3 this.name = name;
 4 this.age = age;
 5 this.from = from;
 6}
 7BasicInfo.generalInfo = "is 3zfp owned object";
 8var basic = new BasicInfo("zfp",100,"ShenZhen");
 9document.write(basic.generalInfo+"<br>");
10document.write(BasicInfo.generalInfo+"<br>");
11BasicInfo.generalInfo = "info is changed";
12document.write(BasicInfo.generalInfo+"<br>");
执行以上代码,将会得到如下结果:
undefined
is 3zfp owned object
info is changed

注意以下几点:
1、以 类名+"."+静态变量名 的方式来声明一个静态变量
2、静态变量并不属于类的某个实例对象所独有的属性,为对象的共享.
3、能以实例对象名+"."+静态变量名来访问。

全局变量:
全局变量即整个系统运行期间有效访问控制的变量,通常是在一个js代码开头定义,如:

1
2var copyright = "3zfp owned";
3var foo =function()
4{
5 window.alert(copyright);
6}
注意以下几点:

1、如果一个变量不用var 来声明,则其被视为全局变量。如:

1var copyright = "3zfp owned";
2var foo =function(fooInfo)
3{
4 _foo = fooInfo;
5 document.write(copyright+"<br>");
6}
7new foo("foo test");
8document.write(_foo+"<br>");
执行代码,将得到如下结果:
3zfp owned
foo test
但是,这个又有一个注意的地方,function是编译期对象,也就是说_foo这个全局变量要在foo对象被实例化后才能被初始化,也就是说如果将
new foo();
document.write(_foo+"<br>");
对调成
document.write(_foo+"<br>");
new foo();
系统将提示 "_foo 未定义"。
2、如果定义了一个和全局变量同名的局部变量属性,如下:

 1
 2
 3var copyright = "3zfp owned";
 4var foo =function(fooInfo)
 5{
 6 var copyright = fooInfo; //同名变量
 7 this.showInfo = function()
 8 {
 9  document.write(copyright+"<br>");
10 }
11}
12new foo("foo test").showInfo();
13document.write(copyright+"<br>");
执行代码,将得到如下结果:
3zfp owned
foo test

原因是由于function 是在编译期间完成变量的定义,也就是foo内部的copyright的定义是在编译期间完成的,其作用域只在foo对象内有效,而与外部定义的全局变量copyright无关。

时间: 2024-09-22 23:17:34

js变量作用域及可访问性的探讨的相关文章

js变量作用域及可访问性的探讨_javascript技巧

每一种语言都有变量的概念,变量是用来存储信息的一个元素.比如下面这个函数:  复制代码 代码如下:  function Student(name,age,from)  {   this.name = name;    this.age = age;   this.from = from;    this.ToString = function()   {    return "my information is name: "+this.name+",age : "

php 变量作用域:js变量作用域

请先看一下代码: var scope = "global";function f() {alert(scope);//dispaly "undefined" not "global"var scope = "local";//Vaeiable initized here,but defined everywherealert(scope);//display "local"}f();为什么了?局部变量在整个

js变量作用域的问题

问题描述 小弟,菜鸟级,求各位大侠赐教:在JS中定义了一个全局变量nowTime;varnowTime;//服务器的当前时间然后通过Ajax从后台获取当前的服务器的时间varnowTimeUrl="${ctx}/ajaxAction.do?method=json&classes=resatServiceImpl&common=getNowTime";//定义后台路径$.getJSON(nowTimeUrl,queryNowTime);//执行回调函数//回调函数func

js变量以及其作用域详解_javascript技巧

一.变量的类型 Javascript和Java.C这些语言不同,它是一种无类型.弱检测的语言.它对变量的定义并不需要声明变量类型,我们只要通过赋值的形式,可以将各种类型的数据赋值给同一个变量.例如: 复制代码 代码如下: i=100;//Number类型 i="variable";//String类型 i={x:4};//Object类型 i=[1,2,3];//Array类型 JS的这种特性虽然让我们的编码更加灵活,但也带来了一个弊端,不利于Debug,编译器的弱检测让我们维护冗长的

js变量、作用域及内存详解_基础知识

基本类型值有:undefined,NUll,Boolean,Number和String,这些类型分别在内存中占有固定的大小空间,他们的值保存在栈空间,我们通过按值来访问的. (1)值类型:数值.布尔值.null.undefined. (2)引用类型:对象.数组.函数. 如果赋值的是引用类型的值,则必须在堆内存中为这个值分配空间.由于这种值的大小不固定(对象有很多属性和方法),因此不能把他们保存到栈内存中.但内存地址大小是固定的,因此可以将内存地址保存在栈内存中. <script type="

js变量的作用域详解

量的作用范围又称为作用域,是指某变量在程序中的有效范围.根据作用域,变量可以分为全局变量和局部变量. 1  全局变量的作用域是全局性的,即在整个网页特效程序中,全局变量处处都在. 2  而在函数内部声明的变量,只在函数内部起作用.这些变量是局部变量,作用域是局部性的:函数的参数也是局部性的,只在函数内部起作用. 相信大家都知道,javascript中变量作用域只有两种,全局作用域与函数中的局部作用域(有人认为不同script节点间也存在一种作用域,称之为段作用域,理由是在后面的script的节点

浅谈php中include文件变量作用域_php实例

在php中我们有时候需要include一个文件.比如我前段时间在写一个框架的时候,打算用原生的php作为模板,然后写一个display方法引入模板文件就可以,但是这只是我的意淫而已. 写完后发现在模板中所有的变量都提示未定义.通过各种研究和查找资料,总结了include文件时的几种情况下的作用域. 第一种情况:A文件include B文件,在B文件中可以调用A中的变量. A文件代码: <?php $aaa = '123'; include "B.php"; B文件代码: <

js变量以及其作用域详解

一.变量的类型  Javascript和Java.C这些语言不同,它是一种无类型.弱检测的语言.它对变量的定义并不需要声明变量类型,我们只要通过赋值的形式,可以将各种类型的数据赋值给同一个变量.例如: i=100;//Number类型  i="variable";//String类型  i={x:4};//Object类型  i=[1,2,3];//Array类型 JS的这种特性虽然让我们的编码更加灵活,但也带来了一个弊端,不利于Debug,编译器的弱检测让我们维护冗长的代码时相当痛苦

js下拉菜单实现与可访问性的思考

一.俗耐的开篇语 关于下拉菜单的可用性问题,我之前一直都是忽略的,可以说是不知道,常常仅仅止步于眼前的效果上.前段时间看到了Roger的"Accessing Nav Drop-Downs"一文,就是讲了下下拉菜单的可用性问题.同时,巧的是,最近在看淘宝UED翻译的<ppk谈JavaScript>一书,其多次提到了可访问性的问题,尤其在p28~p37对JavaScript及其一些可用性问题发表了自己的看法.其中主要的观点和注意事项与Roger的文章是一致的. 这些阅读的经历让