四、数据类型
(一)、typeof 操作符
同来确定任意变量的数据类型。
undefine表示值未定义,boolean表示值为布尔值,string表示值为字符串,number表示值为数值,object表示值为对象或null,function表示值为函数,symbol表示值为符号。
let message = 'hello world'
console.log(typeof message) //string
console.log(typeof(message)) //string
console.log(typeof 95) //number
(二)、undefined类型
undefined类型只有一个特殊值undefined,是一个假值。当声明了变量但没有初始化时相当于给变量赋值了undefined,增加这个特殊值的目的就是为了正式明确对象指针(null)和未初始化变量的区别。
注意:包含undefined值的变量和未定义变量是有区别的。当使用typeof操作符判断两者时返回的值都为undefined。
let message = undefined;
console.log(message) //undefined
console.log(age)//报错未定义
//使用typeof
console.log(typeof message) //undefined
console.log(typeof age) //undefined
(三)、null类型
null类型同样只有一个特殊值null,也是一个假值。逻辑上讲null值表示一个空对象指针,所以用typeof会返回object。undefined是由null派生来的所以ECMA将它们定义为表面相等。
let car = null;
console.log(typeof car) //object
console.log(null == undefined ) //true
(四)、Boolean类型
Boolean(布尔值)类型有两个字面量true和false。(true和false区分大小写)
其他类型的值可以使用Boolean()转型函数,始终返回一个布尔值。
在使用if等流程控制语句时会自动执行转换。
let message = 'hello world';
let messageAsBoolean = Boolean(message);
console.log(messageAsBoolean) //true
转换规则
数据类型 | 转换为true | 转换为false |
---|---|---|
Boolean | true | false |
String | 非空字符串 | ‘’ ’‘ 空字符串 |
Number | 非0数值(包含无穷值) | 0、NAN |
object | 非null任意对象 | null |
Undefined | 不存在 | undefined |
(五)、number类型
number类型有两种格式:整数型和浮点型。
最基本的数值字面量是十进制整数。也可以八进制或十六进制字面量表示。
八进制第一个数字必须是0后面是相应的八进制数字。在严格模式下开头是0o。
十六进制数值前缀为0x后面是十六进制数字。
1、浮点值
定义浮点值数值中必须有小数点后面必须至少有一个数字。
储存浮点值使用的内存空间是储存整数数值的两倍,所以ECMAScript总是想方设法把值转换为整数。在小数点后面没有非零数字的情况下会变成整数。
注意:0.1+0.2 不等于0.3 ,原因是因为使用IEEE754数值。
2、值的范围
由于内存限制,ECMAScript表示的最小值保存在Number.MIN_VALUE中,在多数浏览器中为5e-324.
表示的最大值保存在Number.MAX_VALUE中,在多数浏览器中是1.7976931348623157e+308。
如果计算超出JavaScript的范围会被自动转换为 ±Infinity(无穷值)
要确定一个值是不是介于JavaScript能表示的范围可以使用isFinite()函数
let result = Number.MAX_VALUE + Number.MIN_VALUE;
console.log(result) //false
3、NaN
特殊的数值,意思是不是数值。
用于表示本来要返回数值的操作失败了。
isNaN()函数接受一个参数,可以是任意数据类型,(先转换为数值再进行判断)判断该参数是否不是数值。
//常见NaN
//0,-0或+0相除
console.log(0/0);//NaN
console.log(-0/+0);//NaN
//涉及NaN的操作
console.log(NaN/10);//NaN
//如果是分子是非0值则会返回Infinity或-Infinity
console.log(5/0);//Infinity
console.log(-5/0);//-Infinity
//NaN不等于NaN
console.log(NaN == NaN);//false
//isNaN()函数
console.log(isNaN(NaN));//true
console.log(isNaN(10));//fasle
4、数值转换
可以使用Number()、parseInt()、parseFloat()转型函数转换为数值。
Number()转换规则:
1.布尔值,true 转换为 1,false 转换为 0。
2.数值,直接返回。
3.null,返回 0。
4. undefined,返回 NaN。
5.字符串,应用以下规则。
如果字符串包含数值字符,包括数值字符前面带加、减号的情况,则转换为一个十进制数值。因此,Number(“1”)返回 1,Number(“123”)返回 123,Number(“011”)返回 11(忽略前面的零)。
如果字符串包含有效的浮点值格式如"1.1",则会转换为相应的浮点值(同样,忽略前面的零)。
如果字符串包含有效的十六进制格式如"0xf",则会转换为与该十六进制值对应的十进制整数值。
如果是空字符串(不包含字符),则返回 0。
如果字符串包含除上述情况之外的其他字符,则返回 NaN。
6.对象,调用 valueOf()方法,并按照上述规则转换返回的值。如果转换结果是 NaN,则调用toString()方法,再按照转换字符串的规则转换。
let num1 = Number("Hello world!"); // NaN
let num2 = Number(""); // 0
let num3 = Number("000011"); // 11
let num4 = Number(true); // 1
parseInt()函数:接收第二个参数,用于指定底数(进制数)。更专注于字符串是否包含数值模式。字符串最前面的空格会被忽略,从第一个非空格字符开始转换。如果第一个字符不是数值字符、加号或减号,parseInt()立即返回 NaN。这意味着空字符串也会返回 NaN(这一点跟 Number()不一样,它返回 0)。
let num1 = parseInt("1234blue"); // 1234
let num2 = parseInt(""); // NaN
let num3 = parseInt("0xA"); // 10,解释为十六进制整数
let num4 = parseInt(22.5); // 22
let num5 = parseInt("70"); // 70,解释为十进制值
let num6 = parseInt("0xf"); // 15,解释为十六进制整数
let num1 = parseInt("10", 2); // 2,按二进制解析
let num2 = parseInt("10", 8); // 8,按八进制解析
let num3 = parseInt("10", 10); // 10,按十进制解析
let num4 = parseInt("10", 16); // 16,按十六进制解析
parseFloat()函数与parseInt()函数类似,都是从位置0开始检测每个字符。解析到字符串末尾或解析到一个无效的浮点数字符为止。不同之处是parseFloat()始终忽略字符串开头的0。十六进制始终返回0,它只解析十进制值。
let num1 = parseFloat("1234blue"); // 1234,按整数解析
let num2 = parseFloat("0xA"); // 0
let num3 = parseFloat("22.5"); // 22.5
let num4 = parseFloat("22.34.5"); // 22.34
let num5 = parseFloat("0908.5"); // 908.5
let num6 = parseFloat("3.125e7"); // 31250000
(六)、String类型
String(字符串)数据类型表示零或多个16位Unicode字符序列。使用双引号(“”)、单引号(‘’)、反引号(``)标示。
注意:开头是什么引号结尾也必须是该引号结尾。
let firstName = "John";
let lastName = 'Jacob';
let lastName = `Jingleheimerschmidt`
1、字符串字面量
用于表示非打印字符或其他用途的字符。可以出现在字符串中任意位置,且可以作为单个字符被解释。
字面量 | 含义 |
---|---|
\n | 换行 |
\t | 制表 |
\b | 退格 |
\r | 回车 |
\f | 换页 |
\ \ | 反斜杠(\) |
\ ’ | 单引号(‘),在字符串以单引号标示时使用,例如 ’he said,\ 'hey.\ ‘’ |
\ " | 双引号(”)同上 |
\ ` | 反引号(`)同上 |
\xnn | 以十六进制编码nn表示的字符(其中n是十六进制数字0~F),例如\x41等于‘A’ |
\unnnn | 以十六进制编码nnnn表示的Unicode字符(其中n是十六进制数字0~F),例如\u03a3等于希腊字符‘Σ‘ |
let text = "This is the letter sigma: \u03a3.";
console.log(text.length); // 28
//注意:如果字符串中包含双字节字符,那么返回的length属性也有可能不是准确的字符数。
2、字符串的特点
ECMAScript中的字符串是不可变的。也就是说只要一旦创建,它们的值就不能变了。要修改需要先销毁原始变量然后把新字符串保存到该变量。
3、转换字符串
(1)、toString()
数值、布尔、对象和字符串都有toString()方法,null和undefined,没有toString()方法。
一般不接受参数,在数值调用这个方法时可以接受一个底数参数,即以什么底数参数来输出字符串表示,默认是十进制。
let num = 10;
console.log(num.toString()); // "10"
console.log(num.toString(2)); // "1010"
console.log(num.toString(8)); // "12"
console.log(num.toString(10)); // "10"
console.log(num.toString(16)); // "a"
(2)、String()
它始终会返回表示相应类型值的字符串。遵循如下规则:
1、如果值有toString()方法,调用该方法并返回结果。
2、如果值是null 返回”null"、
3、如果是undefined,返回“undefined”。
let value1 = 10;
let value2 = true;
let value3 = null;
let value4;
console.log(String(value1)); // "10"
console.log(String(value2)); // "true"
console.log(String(value3)); // "null"
console.log(String(value4)); // "undefined"
4、模板字面量
ECMAScript 6 新增了使用模板字面量定义字符串的能力。
模板字面量保留换行符,可以换行定义字符串
保留反引号内部的空格。
5、字符串插值。
模板字符串中可以通过${}插入一个或多个值。所有插值都会使用toString()强制转换为字符串,也可以使用插入JavaScript表达式插值。
let value = 5;
let exponent = 'second';
// 以前,字符串插值是这样实现的:
let interpolatedString =
value + ' to the ' + exponent + ' power is ' + (value * value);
// 现在,可以用模板字面量这样实现:
let interpolatedTemplateLiteral =
`${ value } to the ${ exponent } power is ${ value * value }`;
console.log(interpolatedString); // 5 to the second power is 25
console.log(interpolatedTemplateLiteral); // 5 to the second power is 25
6、模板字符串标签函数
模板字面量也支持定义标签函数(tag function),而通过标签函数可以自定义插值行为。标签函数会接收被插值记号分隔后的模板和对每个表达式求值的结果
let a = 6;
let b = 9;
function zipTag(strings, ...expressions) {
return strings[0] +
expressions.map((e, i) => `${e}${strings[i + 1]}`)
.join('');
}
let untaggedResult = `${ a } + ${ b } = ${ a + b }`;
let taggedResult = zipTag`${ a } + ${ b } = ${ a + b }`;
console.log(untaggedResult); // "6 + 9 = 15"
console.log(taggedResult); // "6 + 9 = 15"
7、原始字符串
使用模板字面量也可以直接获取原始的模板字面量内容(如换行符或 Unicode 字符),而不是被转
换后的字符表示。为此,可以使用默认的 String.raw 标签函数:
// Unicode 示例
// \u00A9 是版权符号
console.log(`\u00A9`); // ©
console.log(String.raw`\u00A9`); // \u00A9
// 换行符示例
console.log(`first line\nsecond line`);
// first line
// second line
console.log(String.raw`first line\nsecond line`); // "first line\nsecond line"
// 对实际的换行符来说是不行的
// 它们不会被转换成转义序列的形式
console.log(`first line second line`);
// first line
// second line
console.log(String.raw`first line second line`);
// first line
// second line
也可以通过标签函数的第一个参数,即字符串数组的.raw 属性取得每个字符串的原始内容
function printRaw(strings) {
console.log('Actual characters:');
for (const string of strings) {
console.log(string);
}
console.log('Escaped characters;');
for (const rawString of strings.raw) {
console.log(rawString);
}
}
printRaw`\u00A9${ 'and' }\n`;
// Actual characters:
// ©
//(换行符)
// Escaped characters:
// \u00A9
// \n