数据类型
ECMAScript有6种简单数据类型Undefined、Null、Boolean、Number、String、和Symbol。一种复杂数据类型叫Object。
typeof操作符
用来确定任意变量的数据类型
'undefined'//表示值未定义
'boolean'//表示值为布尔值
'string'//表示值为字符串
'number'//表示值为数值
'object'//表示值为对象(而不是函数)或null
'function'//表示值为函数
'symbol'//表示值为符号
函数也是一种对象,typeof操作符可以用来区分函数和其他对象。
Undefined类型
当使用var或let声明了变量但是没有赋值时,就相当于给变量赋予了undefined值。这个值是为了正式明确空对象指针(null)和未初始化变量的区别。不必显示地给某个变量设置undefined值,但是最好在声明变量的时候进行初始化,这样,当typeof返回undefined时,你就会知道那是因为给定的变量尚未声明。
在对未初始化的变量调用typeof时,返回的结果是undefined,但对未声明的变量调用它时,返回的结果还是undefined。
Null类型
null值表示一个空指针对象。给typeof传一个null会返回object。在定义将来要保存对象值的变量时,最好使用null来初始化,不要使用其他值。这样只要检查这个变量的值是不是null就可以知道这个变量是否后来被重新赋值了。
Boolean类型
true值不等于1,false不等于0,但是可以转换为数字。
不同类型与布尔值之间的转换规则
数据类型 | 转换为true的值 | 转换为false的值 |
---|---|---|
Boolean | true | false |
String | 非空字符串 | 空字符串 |
Number | 非零数值(包括无穷值) | 0、NaN |
Object | 任意对象 | null |
Undefined | N/A(不存在) | undefined |
Number类型
包括整数和浮点值,八进制用前缀0o表示,十六进制用前缀0x表示
-
浮点值
浮点值可用科学计数法表示。默认情况下,ECMAScript会将小数点后至少包含6个零的浮点值转换为科学计数法。浮点值运算存在误差,计算中出现浮点数要谨慎。
-
值的范围
ECMAScript可以表示的最小数值保存在Number.MIN_VALUE中,最大值保存在Number.MAX_VALUE中。如果计算中超出了这个范围,那么这个数值会被转换为一个特殊的±Infinity(无穷值)。该值无法用于进一步计算,因为没有可用于计算的表示形式。
要确认一个值是不是在值的范围内可以使用isFinite函数
let result = Number.MAX_VALUE + Number.MAX_VALUE; console.log(isFinite(result));//false
-
NaN
表示“不是数值”,指本来要返回数值的操作失败了。例如
console.log(0/0);//NaN
如果分子是非0值,分母是有符号0或无符号0,则会返回±Infinity
console.log(5/0);//Infinity console.log(5/-0);//-Infinity
NaN有几个独特的属性。首先,任何涉及NaN的操作始终返回NaN(如NaN/10),在连续多步计算时这可能是个问题。其次,NaN不等于包括NaN在内的任何值。
console.log(NaN === NaN);//false
isNaN函数接受一个参数,判断是否这个参数是否“不是数值”。该函数会尝试把参数转换为数字后在判断。
console.log(isNaN(NaN));//true console.log(isNaN(10));//false console.log(isNaN('10'));//false,可以转换为数字10 console.log(isNaN('blue'));//true,不可以转换为数字 console.log(isNaN(true));//false,可以转换为1
虽然不常见,但isNaN函数可用于测试对象。此时,首先会调用对象的
valueOf()
方法,然后再确定返回的值是否可以转换为数值。如果不能,再调用toString()
方法并测试其返回值。这通常是ECMAScript内置函数和操作符的工作方式。 -
数值转换
有三个函数可以将非数值转换为数值:
Number()、parseInt()、parseFloat()
。Number()
是转型函数,可用于任何数据类型。后两个函数主要用于将字符串转换为数值。Number()
转换规则:- 布尔值,true转换为1,false转换为0。
- 数值,直接返回。
- null,返回0。
- undefined,返回NaN。
- 字符串,应用如下规则:
- 如果字符串包含数字字符,包括数值字符串前面带加、减号的情况,则转换为一个十进制数值。(忽略前面的零)
- 如果字符串包含有效的浮点值格式如“1.2”,则会转换为相应的浮点值(忽略前面的零)。
- 如果字符串包含有十六进制格式如“0xf”,则会转换为与该十六进制相对于的十进制整数值。
- 如果是空字符,则返回0。
- 如果字符串包含上述情况之外的其他字符,则返回NaN。
- 对象,调用
valueOf()
方法,并按照上述规则转换返回的值。如果转换结果是NaN,则调用toString()
方法,再按照转换字符串的规则转换。
通常在需要得到整数时可以优先使用
parseInt()
函数。字符串最前面的空格会被忽略,从第一个非空格字符开始转换。如果第一个字符不是数值字符、加号或减号,parseInt()
立即返回NaN。这意味着空字符也会返回NaN。如果第一个字符是数值、加号或减号,则继续依次检测每个字符,直到字符串末尾,或碰到非数值字符。比如,“1234blue”会被转换为1234,parseInt()
也能识别不同的整数格式(十进制、八进制、十六进制等)。不同的数值格式很容易混淆,因此
parseInt()
也接受第二个参数,用于指定进制数,如果要解析的值是十六进制,那么可以传入16作为第二个参数。因为不传进制参数相当于让parseInt()
自己决定如何解析,所以为避免解析出错,建议始终传给它第二个参数。parseFloat()
函数的工作方式跟parseInt()
类似,不同之处在于只能解析十进制,且始终忽略字符串开头的零。如果字符串表示整数,则返回整数。
String类型
-
字符字面量
字面量 含义 \n 换行 \t 制表 \b 退格 \r 回车 \f 换页 \\ 反斜杠(\) \’ 单引号 \’’ 双引号 \` 反引号 \xnn 以十六进制编码nn表示的字符(其中n是十六进制数字),如\x41等于A \unnnn 以十六进制nnnn表示的Unicode字符 字符字面量不管多长都只表示一个字符,通过
length
可以获取字符串的长度,但是如果字符串中包含双字节字符,那么返回的值可能不是准确的值。 -
字符串的特点
ECMAScript中的字符串是不可变的,一旦创建,它们的值就不能变了,要修改某个变量中的字符串,必须先销毁原始的字符串,然后将包含新值的另一个字符串保存到该变量。
-
转换为字符串
有两种方式把一个数值转换为一个字符串。首先是使用几乎所有值都有的
toString()
方法。toString()
方法可用于数值、布尔值、对象和字符串值。null和undefined值没有toString()
方法。toString()
方法可以接受一个参数,用来表示以什么进制输出数值的字符串。如果不确定一个值是不是null或undefined,可以使用
String()
转型函数,它遵循如下规则:- 如果值有
toString()
方法,则调用该方法(不传参数)并返回结果。 - 如果值是null,返回“null”。
- 如果值是undefined,返回“undefined”。
用加号操作符给一个值加上一个空字符串也可以将其转换为字符串。
- 如果值有
-
模板字符串
ECMAScript6新增了模板字符串,模板字符串保留换行字符,可以跨行定义字符串:
let myMultiLineString = 'first line\nsecond line'; let myMultiLineTemplateLiteral = `first line second line`; console.log(myMulitLineString); //first line //second line console.log(myMutiLineTemplateLiteral); //first line //second line
由于模板字符串会保持反引号内部的空格,因此在使用时要格外小心。
-
字符串插值
技术上讲,模板字符串不是字符串,而是一种特殊的JavaScript表达式,只不过求值后得到的是字符串。
字符串插值通过在
${}
中使用一个JavaScript表达式实现:let value = 5; let exponent = 'second' let interpolatedTemplateLiteral = `${value} to the ${exponent} power is ${value * value}` console.log(interpolatedTemplateLiteral);//5 to the second power is 25
所有插入的值都会使用
toString()
强制转型为字符串,而且任何JavaScript表达式都可以用于插值。嵌套的模板字符串无须转义:console.log(`Hello, ${`world`}!`);//Hello,World!
将表达式转换为字符串时会调用
toString()
:let foo = { toString: () => 'World' }; console.log(`Hello, ${ foo }!`);//Hello, World
在插值表达式中可以调用函数和方法:
function capitalize(word) { return `${ word[0].toUpperCase() }${ word.slice(1) }`; } console.log(`${ capitalize(`hello`)},${ capitalize('world') }!`);//Hello,World!
此外,模板也可以插入自己之前的值:
let value = ''; function append() { value = `${value}abc` console.log(value); } append();//abc append();//abcabc append();//abcabcabc
-
模板字面量标签函数
模板字面量也支持定义标签函数,而通过标签函数可以自定义插值行为。标签函数会接收被插值记号分隔后的模板和对每个表达式求值的结果。
let a = 6; let b = 9; function simpleTag(string, aValExpression, bValExpression, sumExpression) { console.log(strings); console.log(aValExpression); console.log(bValExpression); console.log(sumExpression); return 'foobar'; } let untaggedResult = `${a} + ${b} = ${a+b}`; let taggedResult = simpleTag`${a} + ${b} = ${a+b}`; //["", "+", "=", ""] //6 //9 //15 console.log(untaggedResult);//'6+9=15' console.log(taggedResult);//'foobar'
-
原始字符串
使用模板字面量也可以直接获取原始的模板字面量,而不是被转义的内容。为此,可以使用默认的
String.raw
标签函数://Unicode示例 //\u00A9是版权符号 console.log(`\u00A9`);//© console.log(String.raw`\u00A9`);//\u00A9
Symbol类型
Symbol(符号)是ECMAScript6新增的数据类型。符号是原始值,且符号实例是唯一、不可变的。符号的用途是确保对象属性使用唯一标识符,不会发生属性冲突的危险。
-
符号的基本用法
符号需要使用
Symbol()
函数初始化。因为符号本身是原始类型,所以typeof
操作符对符号返回symbol。调用
Symbol()
函数时,可以传入一个字符串作为对符号的描述。但是,这个字符串与符号定义或标识王权无关。
Object类型
每个Object实例
都有如下属性和方法。
constructor
:用于创建当前对象的函数。hasOwnProperty(propertyName)
:用于判断当前对象实例(不是原型)上是否有给定的属性。要检查的属性名必须是字符串或符号。isProtorypeof(object)
:用于判断当前对象是否为另一个对象的原型。propertyIsEnumerable(propertyName)
:用于判断给定属性是否可以使用for-in
语句枚举。toLocaleString()
:返回对象的字符串表示,该字符串反应对象所在的本地化执行环境。toString()
:返回对象的字符串表示。valueOf()
:返回对象对应的字符串、数值或布尔值表示。通常与toString()
的返回值相同。