变量的声明
JavaScript 使用关键字 var 来声明变量,可以先声明后赋值,也可以在声明的同时赋值,多个变量同时声明使用逗号(,)分隔。例如:
代码如下 |
复制代码 |
// 先声明,后赋值
var sex;
sex="男";
// 声明的同时进行赋值
var age=22;
var name="张三";
// 同时声明多个变量
var x=1,y=2,z=3; |
// 声明多个变量时用逗号( ,)分开其中,sex、age、name ... 称为 变量名,"男"、22、”张三 ... 称为 变量值。
JavaScript 是弱类型的语言,声明变量时无需声明数据类型,JavaScript 会根据变量内容自动判断数据类型。
JavaScript 变量命名规范:变量必需以 字母、$ 和 _ 开头,不能以数字和其他字符开头。
注意:JavaScript 是区分大小写的,变量 age 不等于 AGE 。
变量的使用
变量声明以后,就可以使用了。
例如,声明了两个变量 x 和 y :
代码如下 |
复制代码 |
var x=2;
var y=3;要想得到 x+y 的值,可以:
var z=x+y;
document.write(z);运行代码,将输出 5 。
|
Y:
未赋值变量
未赋值变量是指已经使用 var 关键字声明,但是没有赋值的变量。
在JavaScript中,未赋值变量有一个默认值,是 undefined ,即” 未定义 “。
例如:
代码如下 |
复制代码 |
var x; // x = undefined
alert(x);
|
运行代码,弹出警告框,显示 undefined 。
注意:未赋值变量不等于未声明的变量。在JavaScript中,引用一个未赋值的变量,其值为 undefined ,引用一个未声明的变量将会引发错误。
例如:
运行代码,没有弹出警告框,打开 Chrome 调试工具(F12),可以看到引发了如下错误:
Uncaught ReferenceError: xyz is not defined
即“未捕获的引用错误:xyz 没有定义”。
这时有人可能会问,上述的两种声明有什么区别,为什 么会有这两种不同的声明方式,这就涉及到javascript中变量的作用域了。在javascript中,变量的作用域包括全局和函数级别的。
全局变量可以声明在函数体外,无论使用上述的哪种声明方式,在函数体外 声明的变量都是全局变量。如:
代码如下 |
复制代码 |
<script type="text/javascript" language="javascript">
var v = 1;
function foo()
{
alert(v);
}
w = 2;
function bar()
{
alert(w);
}
foo();
</script>
|
运行结果:1 2
另外,在函数内部声明的变量如果不使用var关键字,声明的变量也将是全局变量。如:
代码如下 |
复制代码 |
<script type="text/javascript" language="javascript">
function foo()
{
v = 1;
}
foo();
alert(v);
</script>
|
运行结果:1
但是需要注意,这种情况下,若要使用变量,必须先调用声明变量的函数对变量进行初始化, 如foo(),否则,将会出现“变量v未定义”的错误。
全局变量将作为window对象的属性存在,因为可以 通过window.$($表示变量名)访问。当然也可以通过变量名直接访问。下面会讲到为什么有这两种访问方式。
在函数内部通过var关键字声明的变量将是函数级别的变量,其作用域仅仅限于函数内部。如:
代码如下 |
复制代码 |
<script type="text/javascript" language="javascript">
function foo()
{
var v=1;
alert(v);
}
alert(v);
</script>
|
运行结果:1 变量“v”未定义
通过上面的分析,可以发现关键字var主要作用 是定义函数级别的变量。
细心的朋友可以会问,如果在函数内部和外部定义了相同的变量,会是什么样的结果呢?如:
代码如下 |
复制代码 |
<script type="text/javascript" language="javascript">
var v=1;
function foo()
{
alert(v);
var v=2;
}
foo();
</script>
|
运行结果:undefined
!!!!!也许有人会比较郁闷了,v明明白白的定义在函数foo()体外,为什么会是 undefined呢?这就涉及到javascript的解析了。根据经验,javascript对于函数体内变量的解析过程是:
搜索所有的 var关键字,将其变量声明放到函数体的最前面,赋值和使用仍然保持不变,这样,上面的javascript实际上是等同于:
代码如下 |
复制代码 |
<script type="text/javascript" language="javascript">
var v=1;
function foo()
{
var v;
alert(v);
v=2;
}
foo();
</script>
|
照此分析,产生上述 的结果就显而易见了,由于函数内部的变量的优先级高于全局变量的优先级(大部分的编程语言都是这样), 函数内部的变量v覆盖了全局变量v,但是由于在使用函数内部变量v时,它仅仅声明,但未赋值,因此结果是undefined。
如果在方法 体内仍然要使用定义的全局变量v,window对象此时派上大大的用场了,可以通过window.v来访问。如:
代码如下 |
复制代码 |
<script type="text/javascript" language="javascript">
var v=1;
function foo()
{
alert(window.v);
alert(v);
var v=2;
}
foo();
</script>
|
运行结果:2 undefined
变量的作用域
JS中变量的作用域分为全局变量和局部变量,函数内定义的称为局部变量,函数外的称为全局变量。(“函数外的称为全局变量”是相对的,另此处讨论的前提是用var显式声明的变量,函数内不用var定义的变量默认是全局变量,当然忽略var声明变量是不赞成的)。
代码如下 |
复制代码 |
var glob = 4;//函数外声明全局变量
function fun() {
var height = 20; //函数内用var声明的是局部变量
weight = 50; //函数内不用var声明的是全局变量
}
fun();
alert(weight);
|
JS中没有块级作用域,即用大括号{}包含的。Java中则有。在main方法中写入下代码:
代码如下 |
复制代码 |
public static void main(String... args) {
for(int i=0;i<5;i++) {
}
{
int j=10;
}
int z = 20;
System.out.println(i); // i不可见,语法分析时报错,即编译不通过
System.out.println(j); // j不可见,语法分析时报错,即编译不通过
System.out.println(z); // z可见,输出20
}
|
但如果在JS:
代码如下 |
复制代码 |
for(var i=0;i<5;i++) {
}
var obj = {name:"Lily"};
for(var attr in obj) {
}
{
var j=10;
}
alert(i);//输出4,没有块级作用域
alert(attr); //输出name,没有块级作用域
alert(j);//输出10,没有块级作用域
|
这也说明一个问题,避免在全局范围内使用for循环同时声明变量,否则会造成全局命名范围的污染。
当然,JS1.7中提出了let关键字声明变量(见https://developer.mozilla.org/cn/New_in_JavaScript_1.7),只作用于for语句范围。
代码如下 |
复制代码 |
for(let i=0;i<5;i++) {
//todo
}
alert(i);//运行时报错,提示i未定义
|
JS1.7需要这样引用 <script type="application/javascript;version=1.7"/></script>
ps:firefox2+实现了JS1.7 |