zoukankan      html  css  js  c++  java
  • js变量作用域及访问权限的探讨(2)

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

    复制代码 代码如下:
     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 : "+this.age+", from :" +this.from; 
      } 
    }

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

    局部变量:

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

     

    复制代码 代码如下:
    function foo(flag) 

     var sum = 0; 
     if(flag == true) 
     { 
      var index; 
      for(index=0;index<10;index++) 
      { 
       sum +=index; 
      } 

     document.write("index is :"+index+"<br>"); 
     return sum; 

    //document.write("sum is :" +sum+"<br>"); 
    document.write("result is :"+foo(true)+"<br>"); 

       该 代码执行后输出的结果为:“index is :undefined” 和 “result is :0”,我们可以看到希望输出的index变量的值为 undefined,也就是未定义。因此我们可以发现,index变量在if语句块结束后即被销毁了。那么“sum”变量呢?这个变量在foo()函数段 执行完毕后被销毁了,如果您去掉我注释的那条语句,再执行,您将会发现系统将报错。值得注意的是,如果我把上面的foo()函数改成如下: 

     

    复制代码 代码如下:
    function foo(flag) 
     { 
      var sum = 0; 
      for(var index=0;index<10;index++) 
      { 
       sum +=index; 
      } 
      document.write("index is :"+index+"<br>"); 
      return sum; 


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

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

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

    复制代码 代码如下:
    function Student(name,age,from) 


     this.name = FormatIt(name); 
     this.age = age; 
    this.from = from; 
     var origName = name; 
     var FormatIt = function(name) 
     { 
     return name.substr(0,5); 
     } 
     this.ToString = function() 
     { 
      return "my information is name: "+origName+",age : "+this.age+", from :" +this.from; 
     } 


       这里,我们分别定义了一个origName和FormatIt()两个私有变量(按面向对象的解释,应该用类的属性来称呼)。
       我 们把这种情况下的方法也成为变量,因为该情况下的变量是个function类型的变量,而function也属于Object类的继承类。在这种情形下, 如果我们定义了 var zfp = new Student("3zfp",100,"ShenZhen")。但无法通过zfp.origName和 zfp.FormatIt()方式来访问这两个变量的。

    注意以下几点:

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

    复制代码 代码如下:
    function Student(name,age,from) 

     var origName = name; 
     this.name = FormatName(name); 
     this.age = age; 
     this.from = from; 
     var FormatName = function(name) 
     { 
      return name+".china"; 
     } 
     this.ToString = function() 
     { 
      return "my information is name: "+origName+",age : "+this.age+", from :" +this.from; 
     } 

    var zfp = new Student("3zfp",100,"ShenZhen"); 

    代码执行后,将会报"找不到对象"的错误.意思是FormatName()未定义。

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


    复制代码 代码如下:
    function Student(basicinfo) 

     this.basicInfo = basicinfo; 

     var FormatInfo = function() 
     { 
      this.basicInfo.name = this.basicInfo.name+".china"; 
     } 
     FormatInfo(); 

    function BasicInfo(name,age,from) 

     this.name = name; 
     this.age = age; 
     this.from = from; 

    var zfp = new Student(new BasicInfo("3zfp",100,"ShenZhen")); 

    执行代码后,系统将会提示 “this.basicInfo为空或不是对象”的错误。
    基本结论是,私有方法只能访问私有属性,私有属性在声明并赋值后可以在类的任何地方访问,

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

    复制代码 代码如下:
    function BasicInfo(name,age,from) 

     this.name = name; 
     this.age = age; 
     this.from = from; 

    var basicA = new BasicInfo("3zfp",100,"ShenZhen"); 
    basicA.generalInfo = "is 3zfp owned object"; 
    document.write("basicA's generalInfo is : "+ basicA.generalInfo+"<br>"); 
    var basicB = new BasicInfo("zfp",100,"ShenZhen"); 
    document.write("basicB's generalInfo is : "+ basicB.generalInfo+"<br>"); 
    执行该代码后,我们将可以看到如下结果: 
    basicA's generalInfo is : is 3zfp owned object 
    basicB's generalInfo is : undefined 

    静态变量:

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

    复制代码 代码如下:
    function BasicInfo(name,age,from) 

     this.name = name; 
     this.age = age; 
     this.from = from; 

    BasicInfo.generalInfo = "is 3zfp owned object"; 
    var basic = new BasicInfo("zfp",100,"ShenZhen"); 
    document.write(basic.generalInfo+"<br>"); 
    document.write(BasicInfo.generalInfo+"<br>"); 
    BasicInfo.generalInfo = "info is changed"; 
    document.write(BasicInfo.generalInfo+"<br>"); 


    执行以上代码,将会得到如下结果:
    undefined
    is 3zfp owned object
    info is changed

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

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

    复制代码 代码如下:
    var copyright = "3zfp owned"; 
    var foo =function() 

     window.alert(copyright); 

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

    复制代码 代码如下:
    var copyright = "3zfp owned"; 
    var foo =function(fooInfo) 

     var copyright = fooInfo; //同名变量 
     this.showInfo = function() 
     { 
     document.write(copyright+"<br>"); 
     } 

    new foo("foo test").showInfo(); 
    document.write(copyright+"<br>"); 

    执行代码,将得到如下结果:
    3zfp owned
    foo test

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

  • 相关阅读:
    杂谈
    MD语法
    1034 有理数四则运算(20 分)
    1033 旧键盘打字(20 分)
    1032 挖掘机技术哪家强(20 分)
    1031 查验身份证(15 分)
    1030 完美数列(25 分)
    1029 旧键盘(20 分)
    1028 人口普查(20 分)
    1027 打印沙漏(20 分)
  • 原文地址:https://www.cnblogs.com/koleyang/p/4873637.html
Copyright © 2011-2022 走看看