6 种简单数据类型(也称为基本数据类型):
Undefined、Null、Boolean、Number 和 String、symbol (es6新增)
1 种复杂数据类型——
Object
typeof操作符
typeof
用来检测给定变量的数据类型
- "undefined"——如果这个值未定义;
- "boolean"——如果这个值是布尔值;
- "string"——如果这个值是字符串;
- "number"——如果这个值是数值;
- "object"——如果这个值是对象或 null;
- "function"——如果这个值是函数。
var message = "some string";
typeof message;// "string"
typeof(message);// "string"
typeof 95;// "number"
typeof null; // "object"
typeof {}; // "object"
typeof Object;//"function"
typeof 0;// "number"
typeof
是一个操作符
而不是函数,因此例子中的圆括号
尽管可以使用,但不是必需的
Undefined类型
Undefined 类型只有一个值,即特殊的 undefined。在使用 var 声明变量但未对其加以初始化时,这个变量的值就是 undefined,例如:
var message;
alert(message == undefined); //true
包含 undefined 值的变量与尚未定义的变量还是不一样的
var message; // 这个变量声明之后默认取得了 undefined 值
// 下面这个变量并没有声明
// var age
alert(message);// "undefined"
alert(age);// 产生错误
对未初始化和未声明的变量执行 typeof 操作符都返回了 undefined 值
var message; // 这个变量声明之后默认取得了 undefined 值
// 下面这个变量并没有声明
// var age
alert(typeof message);// "undefined"
alert(typeof age);// "undefined"
Null类型
Null 类型是第二个只有一个值的数据类型,这个特殊的值是 null。
null 值表 示一个空对象指针,而这也正是使用 typeof 操作符检测 null 值时会返回"object"的原因。
var car = null;
alert(typeof car);// "object"
如果定义的变量准备在将来用于保存对象,那么最好将该变量初始化为 null
而不是其他值。
实际上,undefined 值是派生自 null 值的
,因此 ECMA-262 规定对它们的相等性测试
要返回 true:
if (car != null){
// 对 car 对象执行某些操作
}
alert(null == undefined); //true
无论在什么情况下 都
没有必要把一个变量的值显式地设置为undefined
(如:var message = undefined;);只要意在保存对象的变量还没有真正保存对象,就应该明确地让该
变量保存 null 值
(var message = null;后期设置 message={};)。
Boolean类型
该类型只有两个字面值:true 和 false。这两个值与数字值不是一回事,因此 true 不一定等于 1,而 false 也不一定等于 0。
Boolean
类型的字面值 true
和 false
是区分大小写的。也就是说,True
和False
(以及其他的混合大小写形式)都不是 Boolean 值,只是标识符。
各种数据类型及其对 应的转换规则:
数据类型 | 转换成true的值 | 转换成false的值 |
---|---|---|
Boolean | true | false |
String | 任何非空字符串 | ""(空字符串) |
Number | 任何非零数字值(包括无穷大) | 0和NaN(参见本章后面有关NaN的内容) |
Object | 任何对象 | null |
Undefined | undefined只有undefined一个值,不会是true |
undefined |
Number类型
Number 类型使用 IEEE754 格式来表示 整数和浮点数值(浮点数值在某些语言中也被称为双精度数值)
!在进行算术计算时,所有以八进制和十六进制表示的数值最终都将被转换成十进制数值
十进制整数
十进制整数可以像下面这样直接在代码中输入:
var intNum = 55; // 整数
八进制
八进制字面值的
第一位必须是零(0)
,然后是八进制数字序列(0~7)
。如果字面值中的数值超出了范围,那么前导零将被忽略
,后面的数值将被当作十进制数值解析
可用parseInt(070,10)
=== 56 转换进制
var octalNum1 = 070;// 八进制的 56
var octalNum2 = 079;// 无效的八进制数值——解析为 79
var octalNum3 = 08; // 无效的八进制数值——解析为 8
十六进制
十六进制字面值的
前两位必须是 0x
,后跟任何十六进制数字(0~9 及 A~F)
。其中,字母 A~F 可以大写,也可以小写。如下面的例子所示:
var hexNum1 = 0xA; // 十六进制的 10
var hexNum2 = 0x1f; // 十六进制的 31
注意:JavaScript 中保存数值的方式,可以保存正零(+0)和负零(-0)。正零和
负零被认为相等。
var s1 =-0; // -0
var s2 = +0; // 0
s1 === s2 //true
1. 浮点数值
浮点数值,就是该数值中必须包含一个小数点,并且小数点后面必须至少有一位数字。(
小 数点前面可以没有整数,但我们不推荐这种写法
)
var floatNum2 = 0.1;
var floatNum3 = .1; // 有效,但不推荐
注意:保存浮点数值需要的内存空间是保存整数值的两倍!!
ECMAScript 会不失时机地将浮点数值 转换为整数值
。显然,如果小数点后面没有跟任何数字,那么这个数值就可以作为整数值来保存
。同样 地,如果浮点数值本身表示的就是一个整数(如 1.0),那么该值也会被转换为整数。
var floatNum1 = 1.; // 小数点后面没有数字——解析为 1
var floatNum2 = 10.0; // 整数——解析为 10
科学计数法:
- 对于那些极大或极小的数值,可以用
e 表示法(即科学计数法)
表示的浮点数值表示。( e 表示法表示的数值等于 e 前面的数值乘以 10 的指数次幂)
var floatNum = 3.125e7; // 等于31250000
3e-17 == 0.00000000000000003
- 在默认情况下,ECMASctipt 会将那些小数点后面带有 6 个零以上的浮点数值转换为以 e 表示法 表示的数值(例如,0.0000003 会被转换成
3e-7
)。
浮点数值的最高精度是 17 位小数
,但在进行算术计算时其精确度远远不如整数
。例如,0.1 加 0.2 的结果不是 0.3,而是 0.30000000000000004。这个小小的舍入误差会导致无法测试特定的浮点数值。 例如:
if (a + b == 0.3){
// 不要做这样的测试! alert("You got 0.3.");
}
1 == 0.99999999999999999 // true
浮点数值计算不精确的原因:
关于浮点数值计算会产生舍入误差的问题,有一点需要明确:这是使用基于 IEEE754 数值的浮点计算的通病,ECMAScript 并非独此一家
;其他使用相同数值格 式的语言也存在这个问题。
2. 数值范围
由于内存的限制,ECMAScript 并不能保存世界上所有的数值。
- ECMAScript 能够表示的最小数值保 存在
Number.MIN_VALUE
。(ECMAScript 能够表示的最小数值保 存在Number.MIN_VALUE === 5e-324
) - 能够表示的最大数值保存在
Number.MAX_VALUE
中。(Number.MAX_VALUE === 1.7976931348623157e+308
)
如果某次计算的 结果得到了一个超出 JavaScript 数值范围的值
,那么这个数值将被自动转换成特殊的 Infinity
值。具 体来说,如果这个数值是负数,则会被转换成-Infinity
(负无穷),如果这个数值是正数,则会被转 换成 Infinity
(正无穷)。
!!!!Infinity 不是能够参与计算的数值。
判断是不是位于最小和最大的数值之间
,可以使用 isFinite()
函数。这个函数在参数位于最小与最大数值之间时会返 回true
,否则返回false
:
isFinite(Infinity) // false
isFinite(1) // true
访问 Number.NEGATIVE_INFINITY
和 Number.POSITIVE_INFINITY
也可以 得到负和正 Infinity
的值。可以想见,这两个属性中分别保存着-Infinity 和 Infinity
。
3. NaN
NaN ,非数值(Not a Number)是一个特殊的数值。
特点:
- 任何涉及到NaN 的操作都会返回NaN( NaN/10)。
- NaN与任何值不相等,包括NaN。
alert(isNaN(NaN));//true
alert(isNaN(10));//false
alert(isNaN("10"));//false
alert(isNaN("blue")); //true
alert(isNaN(true)); //false
数值转换
Number()
parserInt()
parseFloat()
3个函数可以将非数值转换成数值;
(1) Number :
- 如果是
Boolean
,true被转换为1,false为0;Number(true) === 1
- 数字值,只是简单的传入传出;
- null值,返回0;
(Number(null) === 0)
-
undefined
,返回NaN
; - 如果是字符串:
- 如果字符串中只有数字,则将其转换成十进制数值;("1"成为1,"123"成为123,而"011"成为11,忽略了前导0)
- 如果字符串中有浮点格式,如"1.1",则转换成对应的浮点数值(也会忽略前导0)
- 字符串中包含有效的十六进制格式,如"0xf",则转换成相同大小的十进制整数值;
- 如果字符串是空的,转换成0;
- 如果字符串包含除上述格式外的字符,转换成NaN。
- 如果是对象,则调用valueof()方法,然后根据前面规则转换返回的值。如果结果是NaN,则调用对象的toString()方法,再依次按照签名规则转换返回的字符串值。
Number('sdfsdf'); // NaN
Number("") // 0
Number("0011") // 11
Number(true) // 1
Number("0xf") // 15
Number({ha:'123'}) // NaN
Number([2]) // 2
Number([2,3]) // NaN
(2) parseInt
parseInt()函数转换字符串时,更多是看其是否符合数值模式,会忽略字符串前面的空格,直至找到第一个非空格字符。如果第一个字符不是数字或者符号,返回NaN。parseInt可以识别出各种整数格式(十进制、八进制、十六进制)
!!解析八进制请谨慎使用,ECMAScript3 和 ECMAScript5结果不同,如parseInt("70") ,3解析为56,认为是八进制;而5认为是十进制,解析为70。
parseInt("123sdf") // 123
parseInt("") // NaN
parseInt("0xA") // 10(十六进制)
parseInt(32.5) //32
parseInt("70") // 70 (十进制)
注意: 在使用parseInt时,建议提供第二个参数,告诉要使用的进制。
parseInt('070',8) // 56
parseInt('070',10) // 70
当指定了第二个参数时,十六进制可以不带前缀0x
;
parseInt('af',16);//175
parseInt('af');// NaN
(3) parseFloat
和parseInt相似,从第一个字符(0位置)开始解析,一直解析到末尾,或者遇到一个无效的浮点数字字符位置。
- 字符串中第一个小数点是有效的,第二个小数点就是无效的,第二个小数点后的字符将被忽略。
parseFloat("23.234.234") // 23.234
- parseFloat始终会忽略前导0,只能解析十进制,不接受第二个参数。
parseFloat("123bls") // 123
parseFloat("0xa") // 0
parseFloat("123.23") // 123.23
parseFloat("034.34") // 34.34
parseFloat("2.1e4") // 21000
String类型
String 类型用于表示由零或多个 16 位 Unicode 字符组成的字符序列,即字符串。
字符串可以由双引号(")或单引号(')表示。
var firstName = "Nicholas";
var lastName = 'Zakas';
1. 字符字面量
String 数据类型包含一些特殊的字符字面量,也叫转义序列,用于表示非打印字符。
字面量 | 含义 |
---|---|
\n | 换行 |
\t | 制表 |
\b | 空格 |
\r | 回车 |
\f | 进纸 |
|斜杠 | |
' | 单引号 |
" | 双引号 |
\xnn | 以十六进制代码nn表示的一个字符(其中n为0~F)。例如,\x41表示"A" |
\unnnn | 以十六进制代码nnnn表示的一个Unicode字符(其中n为0~F)。例如,\u03a3表示希腊字符Σ |
2. 字符串的特点
ECMAScript 中的
字符串是不可变
的,也就是说,字符串一旦创建,它们的值就不能改变
。要改变 某个变量保存的字符串,首先要销毁原来的字符串
,然后再用另一个包含新值的字符串填充该变量(拼接字符串时速度很慢的原因
)。
如:
var lang = "Java";
lang = lang + "Script";
初始化定义lang
为字符串"java"
,第二行在"java"
后拼接 "Script"
字符串,后台会依次操作:
- 首先创建一个能容纳 10 个字符的 新字符串;
- 然后在这个字符串中填充"Java"和"Script";
- 最后一步是销毁原来的字符串"Java"和字 符串"Script";
因此,在开发中尽量少拼接字符串,否则性能会降低!!
3. 转换为字符串
要把一个值转换为一个字符串有两种方式。:
toString()
和String()
-
toString()
:
数值、布尔值、对象和字符串值
都有toString()
方法。但null
和undefined
值没有这个方法(null和undefined使用toString方法会报错
)。
var num = 1;
num.toString(); // "1"
var hahah; // 未赋值,为undefined
hahah.toString();// Uncaught TypeError: Cannot read property 'toString' of undefined
var found = true;
var foundAsString = found.toString(); // 字符串"true"
toString()可以输出以二进制、八进制、十六进制,乃至其他任意有效进制格式表示的字符串值。(toString可以接收一个参数,用来表示要转换成的进制,默认为十进制
)
var num = 10;
num.toString(); // "10"
num.toString(2); // "1010"
num.toString(8); // "12"
num.toString(10); // "10"
num.toString(16); // "a"
String()
在
不知道要转换的值是不是 null 或 undefined 的情况下,还可以使用转型函数 String()
,这个函数能够将任何类型的值转换为字符串。
String()函数遵循下列转换规则:
- 如果值有 toString()方法,则调用该方法(没有参数)并返回相应的结果;
- 如果值是 null,则返回"null";
- 如果值是 undefined,则返回"undefined"。
Object类型
对象
其实就是一组数据和功能的集合。对象可以通过执行 new 操作符后跟要创建
的对象类型的名称来创建。
var o = new Object();
var o = new Object; // 有效,但不推荐省略圆括号
Object 的每个实例都具有下列属性和方法
:
-
constructor
:保存着用于创建当前对象的函数。对于前面的例子而言,构造函数(constructor)
就是 Object()。 -
hasOwnProperty(propertyName)
:用于检查给定的属性在当前对象实例中(而不是在实例的原型中)是否存在。其中,作为参数的属性名(propertyName)必须以字符串形式指定(例如:o.hasOwnProperty("name"))。 -
isPrototypeOf(object)
:方法用于测试一个对象是否存在于另一个对象的原型链上。(obj.isPrototypeOf(newObj); 检查obj是否存在于newObj的原型链上,即:newObj 继承于obj
)。 -
propertyIsEnumerable(propertyName)
:每个对象都有一个propertyIsEnumerable
方法。此方法可以确定对象中指定的属性是否可以被for...in
循环枚举,但是通过原型链继承的属性除外。如果对象没有指定的属性,则此方法返回false
。 -
toLocaleString()
:返回对象的字符串表示,该字符串与执行环境的地区对应。 -
toString()
:返回对象的字符串表示。 -
valueOf()
:返回对象的字符串、数值或布尔值表示。通常与 toString()方法的返回值
相同。
var obj = {
func: function (){},
height: 100
};
obj.__proto__.width = 100
var newObj = Object.create(obj); // newObj 继承obj
obj.hasOwnProperty('width'); // false
obj.hasOwnProperty('height'); // true
obj.isPrototypeOf(newObj); // true obj是newObj的原型链