一个变量,就是一个用于存放数据的容器。这个数据可能是一个用于累加计算的数字,或者是一个句子中的字符串。变量的独特之处在于它存放的数值是可以改变的。
变量是用来存储数据的,那么有一个重要的概念需要区分。变量不是数据本身,它们仅仅是一个用于存储数据的容器。你可以把变量想象成一个个用来装东西的纸箱子。

变量 - 图1

声明变量

ECMAScript 中的变量是用 var 运算符(variable 的缩写)加变量名定义的。请使用 var 运算符声明变量,变量名需要遵守一些简单的规则,例如:

  1. var greet;
  2. greet = "hi";
  1. var greet = "hi";

在上述第一个例子中,声明了变量 greet 之后,该变量是空的(它没有值 undefined )。如需向变量赋值,请使用等号。
在上述第二个例子中,声明了变量 greet,并把它的值初始化为 “hi”(字符串)。由于 ECMAScript 是弱类型的,所以解释程序会为 greet 自动创建一个字符串值,无需明确的类型声明

一个好的编程习惯是,在代码开始处,统一对需要的变量进行声明。

还可以用一个 var 语句定义两个或多个变量(可以换行):

  1. var greet1 = "hi,how are you?", greet2 = "i'm fine,thank you!";
  2. var name="Gates",
  3. age=56,
  4. job="CEO";

不过用同一个 var 语句定义的变量不必具有相同的类型,如下所示:

  1. var carName = "smart", mileage= 5278;

这个例子除了定义 carName 外,还定义了 mileage,并把它初始化为 5278。即使 carName 和 mileage 属于两种不同的数据类型,在 ECMAScript 中这样定义也是完全合法的。

同一个变量可以存放不同类型的值。这是弱类型变量的优势。
例如,可以把变量初始化为字符串类型的值,之后把它设置为数字值,如下所示:

  1. var mileage= "5278km";
  2. alert(mileage);
  3. mileage= 5278;
  4. alert(mileage);

这段代码将毫无问题地输出字符串值和数字值。但是,使用变量时,好的编码习惯是同一个变量始终存放相同类型的值。

当您向变量分配文本值时,应该用双引号或单引号包围这个值。

当您向变量赋的值是数值时,不要使用引号。如果您用引号包围数值,该值会被作为文本来处理。

重新声明 JavaScript 变量,该变量的值不会丢失
在以下两条语句执行后,变量 carname 的值依然是 “Volvo”:

  1. var carName="Volvo";
  2. var carName;

const
const 关键字用来声明 JavaScript 中的常量(与变量相对,不可修改,但同样是用于存储信息的“容器”。)常量的值不能通过重新赋值来改变,并且不能重新声明。

  1. //定义常量a并赋值为0
  2. const a = 0;
  3. //报错(不能重新赋值)
  4. a = 1;
  5. //报错(不能重新声明)
  6. const a = 2;
  7. //输出0
  8. console.log("a is: " + a);

命名变量

变量名需要遵守两条简单的规则:

  • 第一个字符必须是字母、下划线(_)或美元符号($)

  • 余下的字符可以是下划线、美元符号或任何字母或数字字符

下面的变量都是合法的:

  1. var test;
  2. var $test;
  3. var $1;
  4. var _$te$t2;

变量对大小写敏感。

只是因为变量名的语法正确,并不意味着就该使用它们。变量还应遵守以下某条著名的命名规则:

  • Camel 标记法

首字母是小写的,接下来的字母都以大写字符开头。例如:

  1. var myTestValue = 0, mySecondValue = "hi";
  • Pascal 标记法

首字母是大写的,接下来的字母都以大写字符开头。例如:

  1. var MyTestValue = 0, MySecondValue = "hi";
  • 匈牙利类型标记法

在以 Pascal 标记法命名的变量前附加一个小写字母(或小写字母序列),说明该变量的类型。例如,i 表示整数,s 表示字符串,例如:

  1. var iMyTestValue = 0, sMySecondValue = "hi";

常用前缀,以使示例代码更易阅读:

类型 前缀 示例
数组 a aValues
布尔型 b bFound
浮点型(数字) f fValue
函数 fn fnMethod
整型(数字) i iValue
对象 o oType
正则表达式 re rePattern
字符串 s sValue
变型(可以是任何类型) v vValue

变量声明不是必须的

ECMAScript 另一个有趣的方面(也是与大多数程序设计语言的主要区别),是在使用变量之前不必声明。例如:

  1. var sTest = "hello ";
  2. sTest2 = sTest + "world";
  3. alert(sTest2);

在上面的代码中,首先,sTest 被声明为字符串类型的值 “hello”。接下来的一行,用变量 sTest2 把 sTest 与字符串 “world” 连在一起。变量 sTest2 并没有用 var 运算符定义,这里只是插入了它,就像已经声明过它一样。

ECMAScript 的解释程序遇到未声明过的标识符时,用该变量名创建一个全局变量,并将其初始化为指定的值。

这是该语言的便利之处,不过如果不能紧密跟踪变量,这样做也很危险。最好的习惯是像使用其他程序设计语言一样,总是声明所有变量。

缺省var
Javascript 声明变量的时候,虽然用 var 关键字声明和不用关键字声明,很多时候运行并没有问题,但是这两种方式还是有区别的。可以正常运行的代码并不代表是合适的代码。

  1. // num1为全局变量
  2. // num2为window的一个属性
  3. var num1 = 1;
  4. num2 = 2;
  5. // delete num1; 无法删除
  6. // delete num2; 删除
  7. function model(){
  8. var num1 = 1; // 本地变量
  9. num2 = 2; // window的属性
  10. // 匿名函数
  11. (function(){
  12. var num = 1; // 本地变量
  13. num1 = 2; // 继承作用域(闭包)
  14. num3 = 3; // window的属性
  15. }())
  16. }

let

let允许你声明一个作用域被限制在块级中的变量、语句或者表达式。在 Function 中局部变量推荐使用 let 变量,避免变量名冲突。

  1. let var1 [= value1] [, var2 [= value2]] [, ..., varN [= valueN]];

作用域规则 :let 声明的变量只在其声明的块或子块中可用,这一点与 var 相似。二者之间最主要的区别在于 var 声明的变量的作用域是整个封闭函数。

  1. function varTest() {
  2. var x = 1;
  3. if (true) {
  4. var x = 2; // 同样的变量!
  5. console.log(x); // 2
  6. }
  7. console.log(x); // 2
  8. }
  9. function letTest() {
  10. let x = 1;
  11. if (true) {
  12. let x = 2; // 不同的变量
  13. console.log(x); // 2
  14. }
  15. console.log(x); // 1
  16. }