• javascript权威指南,第4章,变量


    4.1 什么是变量?

    变量是一个和数值相关的名字。我们经常说,变量“包含”或者“存储”了一个值。有了变量,在程序中就可以存储和操作数据了。所以说,变量就是一个用于存储数值的一个名字。

    4.2 变量的类型:

    Javascript是非类型(untype)值的,这就以为着javascript变量可以存放任意类型的的值。因为缺少类型规则,javascript可以快速的将一种类型的值转换成另一种类型的值。例如你想做这样的定义,var string = "s"+10,10是数字,这时候javascript就降10转化为字符串10连接在s后面,结果string = "s10"。相比之下,c,C++是强类型语言,c,c++的变量只能存放它声明了的特定类型的变量。

    4.3 变量的声明

    在javascript程序中使用变量之前,必须先声明。变量使用关键字 var 声明,例如,var i; var m;

    也可以使用一个var 关键字声明多个变量 var i,m;

    还可以在将变量声明和初始化绑定在一起 var i = 10; var string = "message";

    如果一个变量声明,但是并没有初始化。虽然这个变量声明了,但是在给它存入一个值之前,它的初始值为“undefined”;

    由于var声明的变量是永久性的,用delete运算符来删除这些变量将会引发错误。

    重复的声明和遗漏的声明

    使用var多次声明同一变量是合法的。单如果想读取一个未声明变量的值,javascript会生成一个错误。如果尝试给一个未声明的变量赋值,javascript会隐式声明该变量。但是隐式声明的变量为全局变量,即使是只是在一个函数内使用。

    4.4 变量的作用域

    变量的作用域,通俗讲就是变量的在哪个区域内起作用。全局作用域是全局的,即在javascript代码中处处都有定义。局部作用域,只在局部有效。在函数内部声明的变量和函数的参数,就只在函数体内有定义,它们是局部变量。

    在函数体内,局部变量优先级比同名的全局变量优先级高。如果给一个局部变量或参数声明的名字和全局变量相同,那么久有效的隐藏了这个全局变量。

    例如

    var scope = "global";
    
    function checkscope(){
    
       var scope = "local scope";
    
       document.write(scope);
    
    }
    
    checkscope(); //输出 local scope;

    在全局变量声明时,可以不使用关键词var,但是声明局部变量时,一定要加var,否则,他会改变全局变量的值。

    <script type="text/javascript">
       scope = "global"; //声明全局变量,没有使用关键字var
       function checkscope(){
          scope = "local";//声明局部变量,没有使用关键字var,改变了全局变量的值
          document.write(scope);//使用全局变量的值
          myscope = "local";//声明一个新的全局变量
          document.write(myscope);  //使用新的全局变量
       }
       checkscope();//输出 locallocal
       document.write(scope);//输出local
    </script>

    4.4.1 没有块级作用域

    什么是块级作用域:任何一对花括号({和})中的语句集都属于一个块,在这之中定义的所有变量在代码块外都是不可见的,我们称之为块级作用域。

    函数作用域:定义在函数中的参数和变量在函数外部是不可见的。

    c,c++拥有块级作用域

    一个c语言的例子

    void main(){
    
      int i=2;
    
      i--;
    
      if(i){
    
      int j=3;
    
    }
    
    printf("%d\n",j);
    
    }

    结果为 “use an undefined variable:j”,因为c语言拥有块级作用域,j在if块中定义,块外无法访问

    看一个js的例子

    function test(){
    
       for(var i=0;i<3;i++){}
    
       alert(i);
    
    }
    
    test();//结果i=3

    换句话说i能够访问在for块中定义的i,就说明js没有块作用域,但只有函数作用域,即在函数任何部分定义的变量,在该函数中的任何地方都可以访问;

    4.4.2

    未定义的变量和未赋值的变量

    未定义的变量:从未声明的变量;

    为赋值的变量:声明过,但是没有初始化;

    之间的区别

    var i;//定义一个未赋值的变量,调用时为undefined
    
    alert(u);//定义一个未声明的变量,调用时会报错
    
    u = 3; //给一个未声明的变量赋值来声明这个变量

    4.5 基本类型和引用类型

    但是字符串是一个特例,具有可变大小,但是我们希望javascript只是复制字符串的引用而不是他的内容。

    4.6 垃圾收集

    因为引用没有固定类型。javascript每次创建字符串,数组,解释器必须分配内存存储那个实体。javascript可以使用垃圾收集的方法去释放内存。javascript的解释器确定程序中的一个对象是无用的时候(程序中使用的变量再也无法引用这个对象了),即不需要这个对象,可以把它占用内存释放掉了

    var s = "hello";
    
    var u = s.toUpperCase();
    
    s = u;

    代码运行之后,就不能再获得原始的字符串“hello”,因为程序中没有变量再引用它。系统检测到这一事实后,就会释放该字符串的存储空间。

    4.7

    4.7 javascript预编译与运行期过程

    javascript这种解释型语言,分为两个阶段:编译期(类似于预编译,一下统称为“预编译”)与运行期。

    在预编译时期,javascript以函数来划分作用域,然后逐层为其以var声明的变量(建成,var变量)和函数定义开辟内存空间然后为对var变量进行特殊处理,统统赋值为undefined

    运行期是在为var变量与函数定义分配空间后立即执行,并且是逐行往下执行的。

    来看一个例子

    <script type="text/javascript">  
    var a=100;  
    var b=true;  
    function test(){  
        alert(a);  
        alert(b);  
        b=false;  
        alert(b);  
        var a=200;  
        alert(a/2);  
        alert(++Math.PI);  
        alert(Math.PI++);  
    }  
    test();
    </script>

    在预编译以后变量的分布情况

    javascript的运行期,在var变量和函数定义分布内存之后,立即执行,而且是一步一步执行。

    第一行,它为外围作用域的a赋值100;

    第一行,它为外围作用域的b赋值true;

    第三行,进图test()作用域,简称内围作用域;

    第四行,就立即调用内围作用域的a,这时它还没有来得及赋值呢!不过它已经声明过了,因此默认为其赋值为undefined(在预编译阶段,见图),于是alert为undefined

    第五行就调用b时,发现test的作用域内没有b,就往外寻找,而b在第二行就赋值为true,于是alert为true。

    第六行,为一个赋值操作,把外围的b变量改赋为false。于是到第7行时,alert为false。

    作用域总结:变量会首先寻找内围作用域,内围作用域级别比外围高。

  • 相关阅读:
    oracle中 sql%rowcount 使用方法
    【玩转微信公众平台之九】 第一个功能:消息自己主动回复
    silverlight中datagrid数据到处excel
    列表
    Java实现网格中移动字母
    Java实现有理数的循环节
    Java实现有理数的循环节
    Java实现有理数的循环节
    Java实现有理数的循环节
    Java实现有理数的循环节
  • 原文地址:https://www.cnblogs.com/huanhuan8808/p/3043067.html
Copyright © 2020-2023  润新知