变量与值是两个不同的概念:变量相当于容器,值相当于内容。为容器贴个标签,就是变量名。程序根据标签找到内容所在的位置,然后可以对值进行操作。

1、声明变量

在 JavaScript 中,声明变量使用 var 语句:

var a;    //声明一个变量
var a,b,c;//声明多个变量时,应使用逗号运算符分隔变量名

可以在声明中为变量进行赋值。未赋值的变量,则初始化值为 undefined (未定义)值。

var a;       //声明但没有赋值
var b=1;     //声明并赋值
alert(a);    //返回undefined
alert(b);    //返回1

在 JavaScript 中,可以重复声明同一个变量,也可以反复初始化变量的值。

var a=1;
var a=2;
var a=3;
alert(a);    //返回3

JavaScript 允许用户不声明变量,而直接为变量赋值,这是因为 JavaScript 解释器能够自动隐式声明变量。但是隐式声明的变量总是作为全局变量而存在的。

当在函数中不声明就直接为变量赋值时,JavaScript 会把它视为全局变量进行处理。由于是全局变量,函数外代码可以访问该变量的值。

function fun(){
    a = 1;         //未声明直接赋值
    var b  = 2;    //声明并赋值
}
fun();       //调用函数,实现变量初始化
alert(a);    //返回1
alert(b);    //提示语法错误。找不到该变量

但是,如果尝试读取一个未声明的变量的值,JavaScript 会提示语法错误。为变量赋值的过程,实际上 JavaScript 也会隐式进行声明。在使用变量时,应养成良好习惯:先声明,后读写;先赋值,后运算。

var 语句声明的变量是 JavaScript 标准声明变量的方法,同时使用 var 语句声明的变量是永久性的,不能够使用 delete 运算符删除该变量。

var 语句使用是有限制的,它不能在循环或条件结构内条件表达式中使用。例如,下面的都是错误的:

while(var i=0,(i++)<10){    //错误
    alert(i);
}
if(var i=false){    //错误
    alert(i);
}

但是,它可以在 for 或 for-in 结构的条件表达式中使用:

for(var i=0;i<10;i++){
    alert(i);
}
for(var i in document){
    alert(i);
}

2、赋值变量

使用等号(=)运算符来为变量赋值,等号左侧为变量,等号右侧为具体的值。

JavaScript 在预编译期会先预处理声明的变量。但是,变量的赋值操作发生在 JavaScript 执行期,而不是预编译期。

funetion fun(){
    a = 1;    //全局变量 a 赋值为1
    var b = 2;//局部变量 b 赋值为2
}
try{
    alert(a)    //尝试读取全局变量 a
}catch(error){
    alert(error.message);    //显示错误信息:变是a未定义
    alert(a);    //读取全局变量a,返回值为 1
}
fun();    //调用函数
alert(a);    //读取全局变量 a,返回值为 1

在上面示例中,fun() 函数未调用之前,函数内部定义的全局变量是无效的,这是因为在 JavaScript 预编译期,仅对函数名、函数内各种标识符建立索引。只有当在 JavaScript 执行期时,才按顺序为变量进行赋值,并初始化。而在执行期,如果函数未被调用,则函数内代码是不被解析的,所以才有了上面看到的示例演示效果。

根据 JavaScript 解析过程,再看下面的示例:

var a = 1;    //声明并初始化全局变量
(function fun(){
    alart(a);    //返回 underined
    var a = 2;   //声明并初始化局部变量
    alert(a);    //返回2
}()

上面代码显示,由于在函数内部声明了一个同名局部变量 a,所以在预编译期,JavaScript 使用该变量覆盖掉全局变量对于函数内部的影响。而在执行初期,局部变量 a 未赋值,所以在函数第1行代码读取局部变量 a 的值是 undefined,当执行到函数第2行代码时,则为局部变量赋值 2,所以在第3行中就显示局部变量 a 的值为 2。

3、变量作用域

变量的作用域(scope)是指变量在程序中可访问的有效范围,也称为变量的可见性。在 Javascript 中,变最作用域可以分为全局作用域和局部作用域。

(1)全局作用域是指变量在整个页面脚本中都是可见的,可以自由访问。

(2)局部作用域是指变量仅能在声明的函数内部可见,函数外是不允许访问的。

在 JavaScript 程序中,如果不显式声明局部变量会带来严重后果的:

var a = 1;
(function(){
    a = 2;
})()
alert(a);    //结果读取了函数内部封装的代码:2

因些。在函数体内使用全局变量是一种很危险的行为,很可能函就会改变程序中其他部分的使用值。为了避免此类问题的发生,应该养成在函数体内使用 var 语句声明局部变量的习惯。

4、避免函数污染

定义全局变量有 3 种方式:

//在任何函数外面直接执行 var 语句。
var a = 'valuel;

//直接添加一个属性到全局对象上。全局对象是所有全局变量的容器。在Web浏览器中,全局对象名为window
window.a = 'value';

//直接使用未经声明的变量,以这种方式定义的全局变量被称为隐式的全局变量。
a='value';

JavaScript 最为帮糕的就是对全局变量的依赖。由于在所有作用域中都可见,使用全局变量会降低程序的可靠性。

避免使用全局变量,努力减少使用全局变量的方法:

(1)在应用程序中创建唯一一个全局变量,并定义该变量为当前应用的容器。只要把多个全局变量都追加在一个名称空间下,就可以降低与其他应用程序产生冲突的几率,应用程序也会变得更容易阅读

(2)也可以使用函数体将信息隐藏起来,它是另一种有效减少“全局污染”的方法。

var foo = function(){
    var a=1,b=2;
    var bar = function(){
        var b=3,c=4;//a=1,b=3,c=4
        a+=b+c;     //a=8,b=3,c=4
    }               //a=1,b-2,c=undefined
    bar();          //a=1,b=2,c=undefined
}

JavaScript 支持函数作用域,定义在函数中的参数和变量在函数外部是不可见的,且在一个函数中的任何位置定义的变量在该函数中的任何地方都可见。