javascript变量类型,作用域

javascript中有六种数据类型,这六种类型可以分为两大类:基本数据类型和引用类型。基本数据类型包括:undefined,number,string,boolean。引用类型是:object,其实null也是object类型的一种特殊形式。可能有点奇怪的是string类型竟然也是基本数据类型。

这两大类型数据的最大区别就是在内存中的存储位置,基本数据类型都是保存在内存栈中的,因为在定义变量以后,javascript引擎就可以获取这种数据类型的长度,可以在栈内分配固定长度的内存保存这种数据类型。引用类型则是在栈中保存了一个指针,实际的数据是在指针指向的堆内存中保存,由于引用类型的数据长度是不固定的,而且可能随着程序的运行,数据大小是变化的,所以使用堆来保存这种数据类型比较合适。常见的引用类型(object衍生出来的)有数组(Array),日期类型(Date),正则表达式类型(Regexp)等。

我们使用typeof语句可以判断用户是否是六中基本类型,比如一个数组变量arrObj,使用这个表达式typeof arrObj==object返回的值是true。但是如果我们要判断是不是某个具体的引用类型,如某个变量是不是数组(Array)类型,就需要使用instanceof语句,例如arrObj instanceof Array。

在javascript中,变量作用域有点复杂,各个浏览器也有一定的差别,但是大体上还是遵循了ECMA-262标准的。下面就是各种变量作用域的例子

全局作用域,下面的变量就是全局作用域。

<script type="text/javascript">

   var name="Michael";

</script>

局部作用域

<script type="text/javascript">

function message(){

   var msg="welcome to my blog";

}

</script>

上面两种只是比较明显的两种变量的作用域,在进一步介绍作用域之前,需要先了解一下程序运行上下文(execution context)的概念。在javascript的程序中,每一个函数,变量都属于一个上下文中,在全局作用域中定义的变量(函数也是一种变量),它的上下文是window,所以上面的变量name和函数message,都是属于window这个上下文的。window是系统提供的一个上下文。msg的上下文是message函数,在函数中定义的变量都挂在了函数名称代表的上下文中。现在有了两个上下文了,这两个context有什么关系呢?这有涉及到了另外一个概念,上下文链。这个链的主要作用是搜索变量用的,下面的例子详细描述的这种关系

<script type="text/javascript">

   var name="Michael";

   function message(){

       var msg="welcome to my blog";

       function showMessage(){

            var date="2013-11-13";

           alert(name+" "+msg+"  "+date);

       };

       showMessage();

   } 

</script>

上面的程序中涉及到三个上下文window->message->showMessage。其中在showMessage中用到了三个变量name,msg和date。在运行showMessage的使用,首先会在showMessage上下文中查找变量名,如果找不到,如msg,则向上一级的上下文中发出请求,找这个变量名,如果找到,这返回这个变量的值,否则继续向上一级发出请求,直到找到根上下文(window),如果没有找到,则返回一个错误。这就是上下文链的作用,这个链的寻找时单向的,只能下级向上级发起寻找,上级是不能向下级发起寻找请求的,如果我们在message函数中使用date变量会报错。

下面是两种特殊的情况:

1.javascript没有块级作用域,如下面的这种情况,变量msg虽然在if语句块中定义,但是在语句块之外,也可以访问msg变量。因为javascript没有块级作用域,所以在语句块(如for,while,try,with等)中定义的变量,会自动向上找到最近的上下文,并把变量挂到这个上下文上面。注意,catch块比较特殊,除了IE之外,在catch块中定义的变量,在catch块之外是不能访问的,如下面的第二个函数。

<script type="text/javascript">

   function message(){

        var bl=true;       

        if(bl){

             var msg="test1";

        }else

        {

           var msg="test2";

        }

       alert(msg);

   }

  function showError(){

       try{

            var msg="success";

        }catch(e){

             var errorMessage="failed";

        }

       alert(msg);  //正常

       alert(errorMessage); //除了IE,其他的浏览器都报错

 }

</script>

1.没有var指令,直接赋值的变量,都是挂到window上下文中,而不是最近的上下文中,这也说明了var指令的作用。如下面的变量msg,并不是属于函数message,而是属于window对象。如果我们在第二函数showMessage中访问msg,是可以正常获取msg变量的值。但是vMsg却不可以在第二个函数中获取其中的值。

<script type="text/javascript">

function message(){

  msg="test";

  var vMsg="test";

}

function showMessage(){

   alert(msg); //test

   alter(vmsg);// 错误,不能执行

}

</script>

 

最后,再了解一个javascript中的垃圾回收器算法,以前有两种:一是标记清除(mark-and-clean),另一个是引用计数法。现在几乎所有的javascript实现都是使用标记清除法。

标记清除法是当变量超出作用域之后,就打上可以清除的标记(无论用什么方法),当进程空闲的时候就把这部分内容清除掉(或者当内存不足的时候)。由于javascript是嵌入式的语言,在浏览器中尤其明显,内存份额是有限的,所以垃圾回收器和程序的算法尤其重要。尽量不要定义全局变量,定义变量的时候要使用var指令。

引用计数法虽然在javascript语言中不再使用了,但是javascript运行环境中的html的dom对象的实现却还是使用了引用计数的方法作为垃圾回收器的算法,这也是一般windows系统中com组件的使用的算法。如果我们使用dom对象或者activex对象,尽量避免循环引用。如果不能避免,一定要显示的取消引用。如下面例子中的循环引用

 

<script type="text/javascript">

function message(){

   var person=new Object();

   person.name="test";

   var element=document.getElementById("name");

   person.input=element;

   element.obj=person;

}

</script>

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值