(续上)在修改变量值的同时修改值的类型,如下所示:
var message = "hi" ;
message = 100 ; //有效,但不推荐
在这个例子中,变量message 一开始保存了一个字符串值“hi”,然后该值又被一个数字值100取代。虽然我们不建议修改变量所保存值的类型,但这种操作在ECMAScript中完全有效。
有一点注意,即用var操作符定义的变量将成为定义该变量的作用域中的局部变量。也就是说,如果在函数中使用var定义一个变量,那么这个变量在函数退出后就会被销毁,例如:
function test() {
var message = “hi”; //局部变量
}
test();
alert(message); //错误
这里,变量message是在函数中使用var定义的,当函数被调用时,就会创建该变量并为其赋值。而在此之后,这个变量又会立即被销毁,因此,例子中的下一行代码就会导致错误。不过,可以像下面这样省略var操作符,从而创建一个全局变量:
function test(){
message = "hi" ; //全局变量
}
test();
alert(message); // "hi"
这个例子省略了var操作符,因而message就成了全局变量,这样,只要调用过一次test()函数,这个变量就有了定义,就可以在函数外部的任何地方访问到。
虽然省略var操作符可以定义全局变量,但这也不是我们推荐的做法。因为在局部作用域中定义的全局变量很难维护,而且如果有意地忽略了var 操作符,而会由于相应变量不会马上就有定义而导致不必须的混乱。给未经声明的变量赋值在严格模式下会导致抛出ReferenceError错误。
可以使用一条语句定义多个变,只要像下面这样把变量(初始化或不初始化均可)用逗号分隔即可:
var message = “hi”,
found = false,
age = 29;
这个例子定义并初始化了3个变量。同样由于ECMAScript是松散类型的,同样由于ECMAScript是松散类型的,因而使用不同类型初始化变量的操作可以放在一条语句中来完成。虽然代码里的换行和变量缩进不是必需的,但这样做可以提高可读性。
在严格模式下,不能定义名为eval或arguments的变量,否则会导致语法错误。
数据类型
***ECMAScript中有5种简单数据类型(也称为基本数据类型):undefined、Null、Boolean、Number和String。还有一种复杂数据类型---Object,Object本质上是由一组无序的名值对组成。ECMAScript不支持任何创建自定义类型的机制,而所有值最终都将是上述6种数据类型之一。咋一看,好像只有6中数据类型不足以表示所有数据;但是,由于ECMAScript数据类型具有动态性,因此的确没有再定义其他数据类型的必要了。
typeof操作符
鉴于ECMAScript是松散类型的,因此需要有一种手段来检测给定变量的数据类型----typeof 就是负责提供这方面信息的操作符。对一个值使用typeof操作符可能返回下列某个字符串:
“undefinded”---如果这个值未定义;
“boolean”---如果这个值是布尔值;
“string”----如果这个值是字符串;
“number”----如果是这个值是数值;
“object”-----如果这个值是对象或者null;
"function" ----如果这个值是函数
下面是几个使用typeof操作符的例子:
var message = "some string" ; // "string"
alert(typeof message); //"string"
alert(typeof message); //"number"
alert(typeof 95); //"number"
这几天例子说明,typeof 操作符的可以是变量(message),也可以是数值字面量,注意,typeof是一个操作符而不是函数,因此例子中圆括号尽管可以使用,但不是必需的。
有些时候,typeof操作符会返回一些令人迷惑但技术却正确的值,比如,调用typeof null 会返回 "object",因为特殊值null被认为是一个空的对象引用。Safari5及之前的版本、Chrome7及之前版本在对正则表达式调用tyeof操作符时会返回“function”,而其他浏览器在这种情况下会返回“object”。
从技术角度讲,函数在ECMAScript中是对象,不是一种数据类型。然而,函数也确实有一些特殊的属性,因此通过tyeof操作符来区分函数和其他对象是有必要的。
Undefined类型
Undefined 类型只有一个值,即特殊的Undefined。在使用var 声明变量但未对其加以初始化时,这个变量的值就是undefined,例如:
var message ;
alert(message == undefined); //true
这个例子使用undefined值显示初始化了变量message。但我们没有必要这么做,因为未经过初始化的值默认就会取得undefined值。
***一般而言,不存在需要显示地把一个变量设置为undefined 值的情况。字面值undefined的主要目的是用于比较,而ECMA-262第3版中并没有规定这个值。第3版引入这个值是为了正式区分空对象指针与未经过初始化的变量。
不过,包含undefined值的变量与尚未定义的变量还是不一样的。看看下面这个例子:
var message ; //这个变量声明之后默认取得了undefined值
//var age
alert(message); //"undefined"
alert(age); //产生错误
运行以上代码,第一个警告框会显示变量message的值,即“undefined”。而第二个警告框----由于传递给alert()函数的是尚未声明的变量age-----则会导致一个错误。对于尚未声明过的变量,只能执行一项操作,即使用typeof 操作符检测其数据类型(对未声明的变量调用delete不会导致错误,但这样做没什么实际意义。而且在严格模式下确实会导致错误)。
然而,令人困惑的是:对未初始化的变量执行typeof操作符会返回undefined值,而对未声明的变量执行typeof操作符同样也会返回undefined值。来看下面的例子:
var message ; //这个变量声明之后默认取得了undefined值
//下面这个变量并没有声明
//var age
alert(typeof message); //“undefined”
alert(typeof age); //"undefined"
结果表明,对未初始化和未声明的变量执行typeof操作符返回了undefined值;这个结果有其逻辑上的合理性。因为虽然两种变量从角度看本质区别,但实际上无论对哪种变量也不可能执行真正的操作。
即便未初始化的变量会自动赋予undefined值,但显示初始化变化依然是明智的选择。如果能够做到这一点,那么当typeof操作符返回“undefined”值时,我们就知道检测的变量还没有被声明,而不是尚未初始化。
Null类型
Null类型是第二个只有一个值的数据类型,这个特殊的值是null。从逻辑角度来看,null值表示一个空对象指针,而这也是使用typeof操作检测null 值时会返回“object”的原因,如下面的例子所示:
var car = null ;
alert(typeof car); // "object"
如果定义的变量准备在将来用于 保存对象,那么最好将该变量初始化为null 而不是其他值。这样一来,只要直接检查null值就可以知道相应的变量是否已经保存了一个对象的引用,如下面的例子所示:
if( car != null ){
对car对象执行某些操作
}
实际上,undefined值是派生自null值的,因此ECMA-262规定对它们的相等性测试要返回true:
alert(null == undefined); //true
这里,位于null和undefined之间的相等操作符(==)总是返回true,不过要注意的是,这个操作符出于比较的目的会转换其操作数。
尽管null和undefined有这样的关系,但它们的用途完全不同。
Boolean 类型
Boolean类型是ECMAScript中使用得最多的一种类型,该类型只有两个字面值:true和false。这两个值与数字不是一回事,因此true不一定等于1,而false也不一定等于0。以下是为变量赋Boolean类型值的例子:
var found = true ;
var lost = false;
需要注意的是,Boolean类型的字面值true和false是区分大小写的。也就是说,True和False(以及其他的混合大小写形式)都不是Boolean值,只是标识符。
虽然Boolean类型的字面值只有两个,但ECMAScript中所有类型的值都有与这两个Boolean值等价的值。要将一个值转换为其对应的Boolean值,可以调用转型函数Boolean(),如下所示:
var message = "Hello world!";
var messageAsBoolean = Boolean(message) ;
在这个例子中,字符串message被转换成了一个Boolean值,该值被保存在messageAsBoolean变量中。可以对任何数据类型的值调用Boolean()函数,而且总会返回一个Boolean的值。至于返回的这个值是true还是false,取决于要转换值的数据类型及其实际值。
var message = "Hello world";
if( message ){
alert("Value is true”);
}
运行这个示例,就会显示一个警告框,因为字符串message被自动转换了对应的Boolean 值(true)。由于存在这种自动执行的Boolean转换,因此确切地知道在流控制语句中使用的是什么变量,至关重要。错误地使用一个对象而不是一个Boolean值,就有可以彻底改变应用程序的流程。
网友评论