JavaScript 共有两种数据类型分别为:值(基本)数据类型,引用数据类型。其中,
值数据类型有:字符串(String)、数字(Number)、布尔(Boolean)、空(Null)、未定义(Undefined)、符号(Symbol)。
引用数据类型:对象(Object)、数组(Array)、函数(Function)。
注:Symbol 是 ES6 引入了一种新的原始数据类型,表示独一无二的值。
JavaScript 拥有动态类型
JavaScript 拥有动态类型。这意味着相同的变量可用作不同的类型:
var x; // x 为 undefinedvar x = 5; // 现在 x 为数字var x = "John"; // 现在 x 为字符串
字符串(String)
字符串是存储字符(比如 “Bill Gates”)的变量。 字符串可以是引号中的任意文本。您可以使用单引号或双引号:
var name="Bill Gates";var name='Bill Gates';
您可以在字符串中使用引号,只要不匹配包围字符串的引号即可,下述三种写法都是正确的。
var answer="It's alright";var answer="He is called 'Johnny'";var answer='He is called "Johnny"';
下述写法是错误的写法:
var answer="He is called "Johnny"";var answer='He is called 'Johnny'';
String 类型的独特之处在于,它是唯一没有固定大小的原始类型。可以用字符串存储 0 或更多的 Unicode 字符,有 16 位整数表示。
字符串中每个字符都有特定的位置,首字符从位置 0 开始,第二个字符在位置 1,依此类推。这意味着字符串中的最后一个字符的位置一定是字符串的长度减 1:
数字(Number)
JavaScript 只有一种数字类型,Number 类型。这种类型既可以表示 32 位的整数,还可以表示 64 位的浮点数,即数字可以带小数点,也可以不带:
var number1=34.00; //使用小数点来写var number2=34; //不使用小数点来写
八进制数和十六进制数
整数也可以被表示为八进制(以 8 为底)或十六进制(以 16 为底)的变量。八进制变量的首数字必须是 0,其后的数字可以是任何八进制数字(0-7),如下面的代码所示:
var iNum = 070; //070 等于十进制的 56
要创建十六进制的变量,首位数字必须为 0,后面接字母 x,然后是任意的十六进制数字(0 到 9 和 A 到 F)。这些字母可以是大写的,也可以是小写的。例如:
var iNum = 0x1f; //0x1f 等于十进制的 31var iNum = 0xAB; //0xAB 等于十进制的 171
提示:尽管所有整数都可以表示为八进制或十六进制的字面量,但所有数学运算返回的都是十进制结果。
浮点数
要定义浮点值,必须包括小数点和小数点后的一位数字(例如,用 1.0 而不是 1)。这被看作浮点数字面量。例如:
var fNum = 5.0;
对于浮点变量的有趣之处在于,用它进行计算前,真正存储的是字符串。
科学计数法
极大或极小的数字可以通过科学(指数)计数法来书写,可以把一个数表示为数字(包括十进制数字)加 e(或 E),后面加乘以 10 的倍数。例如:
var number1=123e5; // 12300000var number2=123e-5; // 0.00123
ECMAScript 默认把具有 6 个或 6 个以上前导 0 的浮点数转换成科学计数法
特殊的 Number 值
极值
几个特殊值也被定义为 Number 类型。前两个是 Number.MAX_VALUE 和 Number.MIN_VALUE,它们定义了 Number 值集合的外边界。所有 ECMAScript 数都必须在这两个值之间。不过计算生成的数值结果可以不落在这两个值之间。
当计算生成的数大于 Number.MAX_VALUE 时,它将被赋予值 Number.POSITIVE_INFINITY,意味着不再有数字值。同样,生成的数值小于 Number.MIN_VALUE 的计算也会被赋予值 Number.NEGATIVE_INFINITY,也意味着不再有数字值。如果计算返回的是无穷大值,那么生成的结果不能再用于其他计算。
事实上,有专门的值表示无穷大,(如你猜到的)即 Infinity。Number.POSITIVE_INFINITY 的值为 Infinity。Number.NEGATIVE_INFINITY 的值为 -Infinity。
由于无穷大数可以是正数也可以是负数,所以可用一个方法判断一个数是否是有穷的(而不是单独测试每个无穷数)。可以对任何数调用 isFinite() 方法,以确保该数不是无穷大。例如:
var iResult = iNum * some_really_large_number;if (isFinite(iResult)) {alert("finite");}else {alert("infinite");}
NaN值
NaN,表示非数(Not a Number)。NaN 是个奇怪的特殊值。一般说来,这种情况发生在类型(String、Boolean 等)转换失败时。例如,要把单词 blue 转换成数值就会失败,因为没有与之等价的数值。与无穷大一样,NaN 也不能用于算术计算。NaN 的另一个奇特之处在于,它与自身不相等,这意味着下面的代码将返回 false:
alert(NaN == NaN); //输出 "false"
出于这个原因,不推荐使用 NaN 值本身。函数 isNaN() 会做得相当好:
alert(isNaN("blue")); //输出 "true"alert(isNaN("666")); //输出 "false"
布尔(Boolean)
布尔(逻辑)只能有两个值:true 或 false。布尔常用在条件判断中。
即使 false 不等于 0,0 也可以在必要时被转换成 false,这样在 Boolean 语句中使用两者都是安全的。
var x=true;var y=false;
数组(Array)
数组用于存储具有相同类型的数据集合。数组下标是基于 0 的,所以第一个项目是 [0],第二个是 [1],以此类推。
//先创建,再赋值var cars=new Array(); //var cars = [];这种方式也能创建一个数组cars[0]="Saab";cars[1]="Volvo";cars[2]="BMW";//创建一个数组,创建时初始化(condensed array)var cars=new Array("Saab","Volvo","BMW");//创建一个数组,创建时初始化(literal array),语法更简洁var cars=["Saab","Volvo","BMW"];
对象(Object)
对象由花括号分隔。在括号内部,对象的属性以名称和值对的形式 (name : value) 来定义。属性由逗号分隔:
var person={firstName:"John", lastName:"Doe", id:5566};
上面例子中的对象 (person) 有三个属性:firstName、lastName 以及 id。
空格和折行无关紧要。声明可横跨多行:
var person={firstName : "John",lastName : "Doe",id : 5566};
对象属性有两种寻址方式:
name=person.lastName;name=person["lastName"];
未定义(Undefined)
Undefined 这个值表示变量不含有值。是所有没有赋值变量的默认值,自动赋值。
Undefined 类型只有一个值,即 undefined。当声明的变量未初始化时,该变量的默认值是 undefined。
var carName;
测试该变量的值是否等于 undefined:
alert(carName == undefined);//输出 "true"
这段代码将显示 “true”,说明这两个值确实相等。还可以用 typeof 运算符显示该变量的值是 undefined:
alert(typeof oTemp); //输出 "undefined"
提示:值 undefined 并不同于未定义的值。但是,typeof 运算符并不真正区分这两种值。考虑下面的代码:
var oTemp;alert(typeof oTemp); //输出 "undefined"alert(typeof oTemp2); //输出 "undefined"
前面的代码对两个变量输出的都是 “undefined”,即使只有变量 oTemp2 从未被声明过。如果对 oTemp2 使用除 typeof 之外的其他运算符的话,会引起错误,因为其他运算符只能用于已声明的变量上。
例如,下面的代码将引发错误:
var oTemp;alert(oTemp2 == undefined);
当函数无明确返回值时,返回的也是值 “undefined”,如下所示:
function testFunc() {}alert(testFunc() == undefined); //输出 "true"
空(Null)
主动释放一个变量引用的对象,表示一个变量不再指向任何对象地址。
Null 只有一个值 null,表示一个空对象引用。值 undefined 实际上是从值 null 派生来的,因此 ECMAScript 把它们定义为相等的。
var carName=null;alert(carName == undefined); //输出 "true"
尽管这两个值相等,但它们的含义不同。undefined 是声明了变量但未对其初始化时赋予该变量的值,null 则用于表示尚未存在的对象。如果函数或方法要返回的是对象,那么找不到该对象时,返回的通常是 null。
你可以设置为 null 来清空对象:
var person = null; // 值为 null(空), 但类型为对象
你可以设置为 undefined 来清空对象:
var person = undefined; // 值为 undefined, 类型为 undefined
undefined 和 null 的异同
共同点:都是原始类型,保存在栈中变量本地。
不同点:null 和 undefined 的值相等,但类型不等。undefined——表示变量声明过但并未赋过值;null——表示一个变量将来可能指向一个对象。
typeof undefined // undefinedtypeof null // objectnull === undefined // falsenull == undefined // true
垃圾回收
null 和 undefined 是专门释放对象内存的一个程序。
(1)在底层,后台伴随当前程序同时运行;引擎会定时自动调用垃圾回收期;
(2)总有一个对象不再被任何变量引用时,才释放。
声明变量类型
当您声明新变量时,可以使用关键词 “new” 来声明其类型:
var carName=new String;var x= new Number;var y= new Boolean;var cars= new Array;var person= new Object;
JavaScript 变量均为对象。当您声明一个变量时,就创建了一个新的对象。
ECMAScript 原始值和引用值
在 ECMAScript 中,变量可以存在两种类型的值,即原始值和引用值。
原始值
存储在栈(stack)中的简单数据段,也就是说,它们的值直接存储在变量访问的位置。
引用值
存储在堆(heap)中的对象,也就是说,存储在变量处的值是一个指针(point),指向存储对象的内存处。
为变量赋值时,ECMAScript 的解释程序必须判断该值是原始类型,还是引用类型。要实现这一点,解释程序则需尝试判断该值是否为 ECMAScript 的原始类型之一,即 Undefined、Null、Boolean、Number 和 String 型。由于这些原始类型占据的空间是固定的,所以可将他们存储在较小的内存区域 - 栈中。这样存储便于迅速查寻变量的值。
在许多语言中,字符串都被看作引用类型,而非原始类型,因为字符串的长度是可变的。ECMAScript 打破了这一传统。
如果一个值是引用类型的,那么它的存储空间将从堆中分配。由于引用值的大小会改变,所以不能把它放在栈中,否则会降低变量查寻的速度。相反,放在变量的栈空间中的值是该对象存储在堆中的地址。地址的大小是固定的,所以把它存储在栈中对变量性能无任何负面影响。如下图所示:
ECMAScript 原始类型
如前所述,ECMAScript 有 5 种原始类型(primitive type),即 Undefined、Null、Boolean、Number 和 String。ECMA-262 把术语类型(type)定义为值的一个集合,每种原始类型定义了它包含的值的范围及其字面量表示形式。
ECMAScript 提供了 typeof 运算符来判断一个值是否在某种类型的范围内。可以用这种运算符判断一个值是否表示一种原始类型:如果它是原始类型,还可以判断它表示哪种原始类型。
typeof 运算符
typeof 运算符有一个参数,即要检查的变量或值。例如:
var sTemp = "test string";alert (typeof sTemp); //输出 "string"alert (typeof 86); //输出 "number"
对变量或值调用 typeof 运算符将返回下列值之一:
undefined - 如果变量是 Undefined 类型的
boolean - 如果变量是 Boolean 类型的
number - 如果变量是 Number 类型的
string - 如果变量是 String 类型的
object - 如果变量是一种引用类型或 Null 类型的
注释:您也许会问,为什么 typeof 运算符对于 null 值会返回 “Object”。这实际上是 JavaScript 最初实现中的一个错误,然后被 ECMAScript 沿用了。现在,null 被认为是对象的占位符,从而解释了这一矛盾,但从技术上来说,它仍然是原始值。
由于数组也是一个对象,所以在判断数据类型是否是数组时,不能用 typeof (其返回值为 object),可以使用 isArray,instanceof 。
//使用 isArray 方法var cars=new Array("Saab","Volvo","BMW");if (Array.isArray) { // 判断是否支持该方法if(Array.isArray(cars)) {document.write("该对象是一个数组。") ;}}//使用 instanceof 操作符var cars=["Saab","Volvo","BMW"];if (cars instanceof Array) {document.write("该对象是一个数组。") ;}
