js的八大数据类型:Number, String, Boolean, Null, Undefined, Symbol, Object, Bigint.
Undefined
对于一个只申明没有赋初始值的变量,其值是undefined.
let message; // undefined
需要注意的是:对这个message调用typeof返回的是undefined(这很容易理解?!),同时,对一个未申明的变量调用typeof时,也会返回undefined(并不会报错)。
let message;
typeof message; // undefined
typeof age; // undefined
Null
在定义将来要保存对象值的变量时,建议使用
null来初始化。
需要注意的是:对null类型的变量调用typeof会返回'object'
let car = null;
typeof car; // 'object'
Boolean
Boolean值有两个:true和false。
要将一个其他类型的值转换为布尔值,可以调用特定的Boolean()转型函数
const str = 'this is string'; // typeof str === 'string'
const strToB = Boolean(str); // typeof strToB === 'boolean'
需要注意的是:其他类型转Boolean的转换规则是:**除了"", 0, NaN, null, undefined这5个值转Boolean类型后值为false**外,其他的值转Boolean后的值都为true.
Number
进制
const num1 = 45; // 十进制
const num2 = 070; // 八进制,相当于十进制的56.(非严格模式, 严格模式下使用 0o 开头表示八进制数)
const num3 = 080; // ?
num3为十进制的80,
因为若是以0开头,其后面的每位数值若是不超过8则表示八进制数,一旦超过则为十进制。
科学计数法
默认情况下,ECMAScript会将小数点后至少包含6个零的浮点值转换为科学计数法
console.log(0.0000009); // 打印 9e-7
值的范围
ECMAScript的表示的最大数值保存在**Number.MAX_VALUE中,最小值保存在Number.MIN_VALUE**中。超出这两个值则为Infinity/-Infinity
可以使用**window.isFinite()来判断数值是否在有限范围内.若是在有限范围内(不为Infinity),则返回true**,否则返回false。
NaN
特殊值
NaN表示Not a Number。
NaN不等于NaN
需要注意的是:
在ECMAScript中,0、-0、+0之间相除会返回NaN,而**非0值除以0值 **会返回Infinity/-Infinity。
console.log(0 / 0); // NaN
console.log(+0 / 0); // NaN
console.log(0 / -0); // NaN
console.log(5 / 0); // Infinity
console.log(5 / -0); // -Infinity
console.log(5 / +0); // Infinity
可以使用window.isNaN()来判断数值是否**‘不是数值’。为什么说,判断数值是否不是数值呢?因为任何不能转换为数值的值都会导致这个函数返回true**
console.log(window.isNaN(NaN)) // true
console.log(window.isNaN('10')) // false => '10'可以转换为数值10
console.log(window.isNaN('a')) // true
console.log(window.isNaN(true)) // false => true可以转换为数值1
由此不难得知,window.isNaN(var)会尝试将var转换为数值,若是可以转换则为false,不可以转换就为true
其他类型转Number规则
三种方式将非数值类型转换为数值:Number()、parseInt()、parseFloat()
Number()
注意:一元加操作符与
Number()遵循相同的转换规则
-
Number()是转型函数,可用于任何数据类型。 -
Boolean类型:true转为1,false转为0. -
null转为0 -
undefined转为NaN// 注意与null的区别 -
String类型: 从第一个非空字符串开始,最前面的空格会跳过
如果只包含数值(包括合法的正负号,合法的小数点符号),则返回对应的数值。
如果包含十六进制/八进制格式,则返回对应进制转换为十进制后的数
如果是空字符串,则返回
0// 注意与parseInt的区别 如果字符串包含其他字符,则返回
NaN -
Object类型: 首先调用
valueOf()方法,并按照上述规则转换返回的值。 如果没有定义
valueOf()方法,调用toString()方法,再按照转换字符串的规则转换。
parseInt()
parseInt()更注重于**字符串是否包含数值**。
对于**非字符串**则直接返回
NaN
对于**空字符串则返回
NaN** // 注意与Number()的区别
parseInt()接收第二个参数作为进制底数,即表示按第二个参数对应的进制数解析。//网红面试题警告~
- 从第一个非空字符串开始,最前面的空格会跳过
- 如果第一个字符不是数值字符、加号或减号。则直接返回
NaN - 会转换数字字符直到遇到第一个非数字字符。
- 对于十六进制/八进制。若是包含非限定字符(比如:
0xAg,包含了g不在a-f,0-9内),则直接返回NaN。否则返回对应进制转十进制后的数值
parseFloat()
parseFloat()的解析方式与parseInt()的方式类似.
需要注意的是:parseFloat()只解析十进制值,因此不能指定底数
String
字符串是不可变的
如果字符串中包含双字节字符,则
length属性返回的值可能不是准确的字符数。??未验证!
其他类型转String规则
两种方法:toString()、String()
toString()
null和undefined没有toString()方法
toString()方法可用于数值,布尔值,对象(注意与其转Number的区别)和字符串。
没毛病,字符串也有
toString()方法。该方法只是简单的返回自身的一个副本
注意了,多数情况下,toString()不接受任何参数。但是,如果调用者是数值,toString()也可以接收一个底数参数,表示将数值 转换为对应的进制之后 再输出字符串。
String()
怎么将null,undefined转换为String?
可以使用String(),它始终返回表示相应类型的字符串。
转换规则如下:
- 如果值有
toString()方法,则调用该方法(不传参数)并返回结果 - 如果值是
null,则返回'null' - 如果值是
undefined,则返回undefined
补充:用加号操作符给一个值加上一个空字符串""也可以将其转换为字符串
模板字面量
值得一提的是:模板字面量标签函数。通过这个自定义插值行为...
标签函数的形式应该都是第一个参数为字符串数组,以及其他内容
let a = 6, b = 9
const str = `${a} + ${b} = ${a + b}`
const customStr = simpleTag`${a} + ${b} = ${a + b}`
console.log(str) // '6 + 9 = 15'
console.log(customStr) // 'this is custom str: 6 + 9 = 15'
function simpleTag(strings, ...expressions) {
// strings[0] === ["", " + ", " = ", ""]
return 'this is custom str: ' + strings[0] + expressions.map((item, i) => `${item}${strings[i + 1]}`).join('')
}
需要知道的是:
- 标签函数的第一个参数永远是以插值分割字符串<类似split(插值)>的数组,其长度永远是n+1
- 而对于有n个插值的模板字面量,传给标签函数的表达式的个数始终是n
原始字符串
通过借用模板字面量可以直接获取原始的模板字面量内容(如换行符),而不是转义后的字符串表示。
标签函数的第一个字符串数组会包含一个raw属性,可以返回数组每一项的原始字符串
// 默认字符串数组没有
可以使用默认的**String.raw标签函数**来获取原始字符串的内容:
const str1 = `a\nb`
const str2 = String.raw`a\nb`
console.log(str1)
/*
a
b
*/
console.log(str2)
// a\nb
Symbol
符号是原始值,且符号实例是唯一、不可变的
符号用来创建唯一记号
Symbol()函数不能与new关键字一起作为构造函数使用。这是为了避免创建对象包裹的symbol
...
不清楚... 不明白... 不透彻....
...
当symbol作为对象属性时:
使用for...in 获取不到symbol属性
Object.getOwnPropertyNames()返回对象实例的常见属性数组;Object.getOwnPropertySymbols()返回对象实例的symbol属性数组 // (它返回的结果是互斥的,也就是说数组不可能包含另一个数组的数组项)
Reflect.ownKeys()返回这两种类型的键