JavaScript变量与数据类型详解

变量

变量来源于数学,是计算机语言中能储存计算结果或能表示值抽象概念。变量可以通过变量名访问。

变量的作用就是用于存储值。

语法:

声明变量时,总是以关键字var打头。任何情况下都应该这样做。然后给变量指定名称。在声明变量时,也可以给它赋值,方法是在变量名后面加上等号和值。赋值语句总是以分号结束。

var 变量名;
//或
var 变量名 = 值;

说明:尽管省略关键字var,JavaScript也不会报错,但是这会导致变量变成全局变量,在JavaScript使用全局变量并不是一个好习惯。分号也不是必须的,但是加上分号可读性更好,同时也能避免代码压缩时出错。

示例:

var msg;
var age = 20;
var sex = 'Male';
var isReal = true;

JavaScript的变量是松散类型的,在JavaScript中声明变量无需指定数据类型,它可以用来保存任何类型的数据。正是由于定义变量时无需指定类型,所以在JavaScript中变量的类型并不是固定的,比如上面的isReal变量本来是布尔型的,但是你也可以再把一个字符串赋给isReal变量,如isReal = "ABC";,所以说,变量仅仅是一个用于保存值的占位符。

对于未赋值的变量,系统会默认给一个undefined值,上面示例中的msg的值就是undefined

变量的数据类型

ECMAScript中有5种基本数据类型和1种引用类型。

基本数据类型:

undefined, null, boolean, number, string

引用数据类型:

object

typeof操作符

鉴于ECMAScript是松散类型的,因此需要有一种手段来检测给定变量的数据类型——typeof 就是负责提供这方面信息的操作符。对一个值使用 typeof 操作符可能返回下列某个字符串:

  • "undefined"——如果这个值未定义;
  • "boolean"——如果这个值是布尔值;
  • "string"——如果这个值是字符串;
  • "number"——如果这个值是数值;
  • "object"——如果这个值是对象或 null;
  • "function"——如果这个值是函数。

下面是几个使用 typeof 操作符的例子:

var msg = "itbsl";
alert(typeof msg);  //string
alert(typeof(msg)); //string
alert(typeof 25);   //number

这几个例子说明,typeof 操作符的操作数可以是变量(msg),也可以是数值字面量。注意,typeof 是一个操作符而不是函数,因此例子中的圆括号尽管可以使用,但不是必需的。

有些时候,typeof 操作符会返回一些令人迷惑但技术上却正确的值。比如,调用 typeof null
会返回"object",因为特殊值 null 被认为是一个空的对象引用。

从技术角度讲,函数在 ECMAScript 中是对象,不是一种数据类型。然而,函数也确实有一些特殊的属性,因此通过 typeof 操作符来区分函数和其他对象是有必要的。

undefined

Undefined 类型只有一个值,即特殊的 undefined。在使用 var 声明变量但未对其加以初始化时, 这个变量的值就是 undefined,例如:

var message;
alert(message == undefined); //true

这个例子只声明了变量 message,但未对其进行初始化。比较这个变量与 undefined 字面量,结果表明它们是相等的。

一般而言,不存在需要显式地把一个变量设置为 undefined 值的情况。字面值undefined 的主要目的是用于比较,而 ECMA-262 第 3 版之前的版本中并没有规定这个值。第 3 版引入这个值是为了正式区分空对象指针与未经初始化的变量。

哪些情况下的值会是undefined呢?

  • 没有return语句的函数的返回值
  • 未赋值的变量的值
  • 稀疏数组中不存在的数组元素的值
  • 访问不存在的属性的值
  • 访问已删除属性的值

稀疏数组是有些索引处有值,而其他索引处没有值得数组。假设有一个长度为10的数组,在索引1000处添加一个新元素后,索引10~999处的值都是undefined。你可以这样认为,这犹如创建了989个变量,但没有对它们进行初始化。虽然这些变量没有值,但它们都要占用计算机内存,因此除非有充分的理由,否则千万不要创建稀疏数组。请注意,undefined是一个值,而不是字符串,undefined和字符串"undefined"并不是一个东西。

undefined到底是什么呢?它其实并不复杂。你可以这么认为:对于任何还没值(即还未初始化)的东西,都会将undefined赋给它。

undefined值的类型为什么是undefined?

我认为原因如下:它不是对象,不是数字、字符串或布尔值,也不是任何明确的东西。既然如此,为何不将这种类型也视为未定义的呢?这是JavaScript怪异的灰色地带之一,你不得不接受。

null

Null 类型是第二个只有一个值的数据类型,这个特殊的值是 null。从逻辑角度来看,null 值表示一个空对象指针,而这也正是使用 typeof 操作符检测 null 值时会返回"object"的原因,如下面
的例子所示:

var car = null;
alert(typeof car); //"object"

如果定义的变量准备在将来用于保存对象,那么最好将该变量初始化为 null 而不是其他值。这样一来,只要直接检查 null 值就可以知道相应的变量是否已经保存了一个对象的引用。

实际上,undefined 值是派生自 null 值的,因此 ECMA-262 规定对它们的相等性测试要返回 true:

alert(null == undefined);    //true

这里,位于 null 和 undefined 之间的相等操作符(==)总是返回 true,不过要注意的是,这个操作符出于比较的目的会转换其操作数。

尽管 null 和 undefined 有这样的关系,但它们的用途完全不同。如前所述,无论在什么情况下都没有必要把一个变量的值显式地设置为 undefined,可是同样的规则对 null 却不适用。换句话说,只要意在保存对象的变量还没有真正保存对象,就应该明确地让该变量保存 null 值。这样做不仅可以体现 null 作为空对象指针的惯例,而且也有助于进一步区分 null 和 undefined。

我们在使用getElementById获取dom对象时,如果指定的id不存在,它返回的值是null,而不是undefined。null到底是什么?getElementById为何不返回undefined?

答: 在很多语言中,都有一个表示”无对象“的概念,这挺好。就拿方法document.getElementById来说吧,是不是要求它返回一个对象?如果它无法返回一个对象呢?在这种情况下,我们希望返回一个含义如下的值:要是有对象,我就会是一个对象,可当前没有。这正是null的含义。我们以后还会经常碰到将变量的值显式的设置为null,意思是说我原本要将一个对象赋给这个变量,但现在没有这样的对象。你可能挠着头说,为何不使用undefined来表达这种意思呢?很多人都这么想。原因是JavaScript刚面世时时这么想的:用一个值表示变量还未初始化,用另一个值表示没有对象可赋给变量。这并不完美,而且显得有些多余,但现实情况就是如此。你只需牢记undefined和null各自的用途,并知道下面一点就行了:在应该提供一个对象,但无法创建或找到时,将提供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,取决于要转换值的数据类型及其实际值。下表给出了各种数据类型及其对应的转换规则。

数据类型 转换为true的值 转换为false的值
Boolean true false
String 任何非空字符串 ""(空字符串)
Number 任何非零数字值(包括无穷大) 0和NaN
Object 任何对象 null
Undefined undefined

这些转换规则对理解流控制语句(如if语句)自动执行相应的Boolean转换非常重要,请看下面的代码:

var message = "Hello world!";
if (message){
    alert("Value is true");
}

运行这个示例,就会显示一个警告框,因为字符串 message 被自动转换成了对应的 Boolean 值 (true)。由于存在这种自动执行的 Boolean 转换,因此确切地知道在流控制语句中使用的是什么变量 至关重要。错误地使用一个对象而不是一个 Boolean 值,就有可能彻底改变应用程序的流程。

number

Number 类型应该是 ECMAScript 中最令人关注的数据类型了,这种类型使用 IEEE754 格式来表示整数和浮点数值(浮点数值在某些语言中也被称为双精度数值)。

数值范围

由于内存的限制,ECMAScript 并不能保存世界上所有的数值。ECMAScript 能够表示的最小数值保 存在 Number.MIN_VALUE 中——在大多数浏览器中,这个值是 5e-324;能够表示的最大数值保存在 Number.MAX_VALUE 中——在大多数浏览器中,这个值是 1.7976931348623157e+308。如果某次计算的 结果得到了一个超出 JavaScript 数值范围的值,那么这个数值将被自动转换成特殊的 Infinity 值。具 体来说,如果这个数值是负数,则会被转换成-Infinity(负无穷),如果这个数值是正数,则会被转 换成 Infinity(正无穷)。

如上所述,如果某次计算返回了正或负的 Infinity 值,那么该值将无法继续参与下一次的计算, 因为 Infinity 不是能够参与计算的数值。要想确定一个数值是不是有穷的(换句话说,是不是位于最 小和最大的数值之间),可以使用 isFinite()函数。这个函数在参数位于最小与最大数值之间时会返 回 true,如下面的例子所示:

var result = Number.MAX_VALUE + Number.MAX_VALUE;
alert(isFinite(result)); //false

尽管在计算中很少出现某些值超出表示范围的情况,但在执行极小或极大数值的计算时,检测监控这些值是可能的,也是必需的。

NaN

NaN,即非数值(Not a Number)是一个特殊的数值,这个数值用于表示一个本来要返回数值的操作数未返回数值的情况(这样就不会抛出错误了)。例如,在其他编程语言中,任何数值除以 0 都会导致错误, 从而停止代码执行。但在 ECMAScript 中,0除以 0 会返回 NaN,正数除以 0 返回 Infinity,负数除以 0 返回-Infinity,因此不会影响其他代码的执行。

NaN 本身有两个非同寻常的特点。首先,任何涉及 NaN 的操作(例如 NaN/10)都会返回 NaN,这个特点在多步计算中有可能导致问题。其次,NaN 与任何值都不相等,包括 NaN 本身。例如,下面的代码会返回 false:

alert(NaN == NaN); //false

针对 NaN 的这两个特点,ECMAScript 定义了 isNaN()函数。这个函数接受一个参数,该参数可以
是任何类型,而函数会帮我们确定这个参数是否“不是数值”。isNaN()在接收到一个值之后,会尝试
将这个值转换为数值。某些不是数值的值会直接转换为数值,例如字符串"10"或 Boolean 值。而任何
不能被转换为数值的值都会导致这个函数返回 true。请看下面的例子:

alert(isNaN(NaN));    //true
alert(isNaN(10));     //false(10 是一个数值)
alert(isNaN("10"));   //false(可以被转换成数值 10)
alert(isNaN("blue")); //true(不能转换成数值)
alert(isNaN(true));   //false(可以被转换成数值 1)

这个例子测试了 5 个不同的值。测试的第一个值是 NaN 本身,结果当然会返回 true。然后分别测试了数值 10 和字符串"10",结果这两个测试都返回了 false,因为前者本身就是数值,而后者可以被转换成数值。但是,字符串"blue"不能被转换成数值,因此函数返回了 true。由于 Boolean 值 true可以转换成数值 1,因此函数返回false。

既然NaN(Not a Number)指的是”不是数字“,那它是什么呢?如果指出它是什么,而非它不是什么,是不是更容易理解呢?那你认为它是什么呢?为获得一点线索,可检查类型:

var test = 0/0;
console.log(typeof test); //number

到底是怎么回事儿?NaN的类型是数字?一个不是数字的东西,其类型怎么可能是数字呢?你可以这样想:NaN是一个糟糕的名称;与其称之为”不是数字“,还不如称之为”无法表示的数字“(必须承认,这样首字母缩写将不那么出色)。如果这样想,就可以认为NaN是一个数字,只是无法表示而已(至少对计算机来说如此)。

string

String 类型用于表示由零或多个 16 位 Unicode 字符组成的字符序列,即字符串。字符串可以由双引号(")或单引号(')表示,因此下面两种字符串的写法都是有效的:

var firstName = "Nicholas";
var lastName = 'Zakas';

与 PHP 中的双引号和单引号会影响对字符串的解释方式不同,ECMAScript 中的这两种语法形式没有什么区别。用双引号表示的字符串和用单引号表示的字符串完全相同。

其它类型数据和字符串进行+操作时,会将其它类型数据转为字符串,然后同字符串拼接。

var num = 3;
var isTrue = true;
var str = "123";

var result1 = num + str;
var result2 = isTrue + str;
alert(result1); //3123
alert(result2); //true123
posted @ 2018-11-22 17:26  itbsl  阅读(834)  评论(0编辑  收藏  举报