这是我参与8月更文挑战的第2天,活动详情查看8月更文挑战
前言
数据值是一门编程语言进行生成的材料,JavaScript 也不例外。JS 中的数据类型,是学习 JavaScript 的基础,主要分成两类:基本数据类型和引用数据类型:
- 基本数据类型:number、string、boolean、null、undefined、还有 ES6 新语法规范中的 Symbol、BigInt
- 引用数据类型:对象(普通对象、数组对象、正则对象、日期对象、Math、Date)、函数 今天我们主要先了解下基本数据类型。
number
包括:
- 常规数字(整数、浮点数)
- 特殊数值
- NaN:(not a number)代表不是一个有效的数字,但是属于number类型的
- Infinity:正无穷大,数学概念中的无穷大,是一个比任何数字都大的特殊值
- -Infinity:负无穷大
思考:如何变量 num 是否为一个有效数字?
if (Number(num) == NaN) {
alert('num不是有效数字!');
}
上面这种方案可行吗?答案是不可以的。NaN 和谁都不相等,条件永远不成立(即使 num 确实不是有效数字,转换的结果确实是 NaN ,但是NaN != NaN的)
这里我们可以使用到一个方法:isNaN
isNaN:检测当前值是否不是有效数字,返回 true,代表不是有效数字,返回 false,是有效数字
- true 是非有效数字
- false 是有效数字
// 语法:isNaN([value])
let num = 12;
isNaN(num); // 检测num变量存储的值是否为有效数字 false
isNaN('13'); // => false
isNaN(true); // => false
isNaN(false); // => false
isNaN(null); // => false
isNaN(undefined); // => true
isNaN({age:9}); // => true
isNaN([12,13]); // => true
isNaN([12]); // => false
isNaN(/^$/); // => true
isNaN(function(){}); // => true
isNaN 检测的机制
- 首先验证当前要检测的值是否为数字类型的,如果不是,浏览器会默认的把值转换为数字类型
- 当前检测的值已经是数字类型,是有效数字,返回 false,不是,返回 true「数字类型中只有NaN不是有效数字,其余都是有效数字」
其他数据类型转成数字类型
Number
上面说到,浏览器会默认的把值转换为数字类型,直接使用Number这个方法转换的
定义:JS 内置的转换方法
【字符串转数字】
- 只要是有效数字字符的,才可以转换成数字,NaN 如果当前字符串中出现任意一个非有效数字字符,结果则为 NaN
- 空字符串转数字,结果是 0
Number('13') // => 13
Number('13px') // => NaN 如果当前字符串中出现任意一个非有效数字字符,结果则为 NaN
Number('13.5') // => 13.5 可以识别小数
Number('13.5.0') // => NaN
Number('') // => 0
【布尔转数字】
Number(true) // => 1
Number(false) // => 0
【其它转数字】
Number(null) // => 0
Number(undefined) // => NaN
特殊:
Number('') // => 0
[].toString() // => ''
// => isNaN([]) =>isNaN('') => false
一般都是基本数据类型转换成数字类型,很少引用数据类型转换成数字类型的。
parseInt
定义:从字符串最左边字符开始查找有效数字字符,并且转换为数字,但是一旦遇到一个非有效数字字符,查找结束。把一个字符串中的整数部分解析出来
parseFloat
跟 parseInt 的区别:把一个字符串中的小数(浮点数)部分解析出来,其他是一样的。
parseInt('13.5px') // => 13
parseFloat('13.5px') // => 13.5
parseInt('width:13.5px')
// => NaN 从字符串最左边字符开始查找有效数字字符,并且转换为数字
// 但是一旦遇到一个非有效数字字符,查找结束
Number、parseInt、parseFloat 的区别
主要区别:在于字符串转换分析上
- Number:出现任意非有效数字字符,结果就是 NaN
- parseInt:把一个字符串中的整数部分解析出来
- parseFloat:把一个字符串中的小数(浮点数)部分解析出来
string
定义:用单引号或者双引号或反引号包裹起来的都是字符串。
其他数据类型转成字符串类型
- 基于 alert / confirm / prompt / document.write 等方法输出内容的时候,会把输出的值转换为字符串,然后再输出
alert(1) // => '1'
- 基于“+”进行字符串拼接的时候
- 把引用类型值转换为数字的时候,首先会转换为字符串,然后再转换为数字
- 给对象设置属性名,如果不是字符串,首先转换为字符串,然后再当做属性存储到对象中(对象的属性只能是数字或者字符串)
- 手动调用 toString/toFixed/join/String 等方法的时候,也是为了转换为字符串
let n = Math.PI;
n.toFixed(2) // "3.14"
let ary = [12,23,34];
ary.join('+') // => '12+23+34'
转换规律:
调用的方法:toString
【除了对象,都是你理解的转换结果】
1 -> '1'
NaN -> 'NaN'
null -> 'null'
[] -> ''
[13] -> '13'
[12,13] -> '12,13'
【对象转字符串】
(function(){}).toString() // "function(){}"
new Date().toString() //"Thu Jul 18 2019 10:03:32 GMT+0800 (中国标准时间)"
({name:'xxx'}).toString(); // => "[object Object]"
().toString(); // => "[object Object]"
// 不管是啥样的普通对象,最后结果都一样的
boolean
只有两个值:true / false
其他数据类型转成布尔类型
- Boolean
- ! 取反
- !! 两次取反,等价于没取反,也就剩下转换为布尔类型了,项目当中常用这个
Boolean(1) // => true
Boolean(0) // => false
Boolean(-1) // => true
Boolean(NaN) // => false
!'追梦玩家' // => false 先把其它数据类型转换为**布尔类型**,然后**取反**
!0 // => true
!'' // => true
!!null // => 取两次反,等价于没取反,也就剩下转换为布尔类型了
规律 5个falsy:
在JS当中只有"0 / NaN / 空字符串'' "" / null / undefined"这个5个值转换为布尔类型的 false,其余都转换为 true
null && undefined
都代表空或者没有
- null:空对象指针
- undefined:未定义
null:一般都是意料之中的没有,先让他暂时没有,后期再给他加上去。(通俗理解:一般都是人为手动的先赋值为 null,后面的程序中我们会再次给它赋值)
let num = null; // => null是手动赋值,预示着后面我会把num变量的值进行修改
...
num = 13;
undefined 代表没有,一般都不是人为手动控制的,大部分都是浏览器自主为空。(后面可以赋值也可以不赋值)
let num; // 声明一个变量 num => 此时变量的值,浏览器给分配的就是undefined
// 获取一个对象的属性值,如果这个对象没有这个属性名,得到的值就是 undefined
let person = { name: '追梦玩家' };
console.log(person.name); // 追梦玩家
console.log(person.age); // undefined
...
// 后面可以赋值也可以不赋值
Symbol
它是用来做什么的呢? 为了说明 Symbol 的作用,我们结合例子来讲解:
由于没有访问限制,JavaScript 曾经有一个惯例:私有属性以下划线起始来命名。 这样不仅无法隐藏这些名字,而且会搞坏代码风格。 现在有了 Symbol,就可以利用 Symbol 来隐藏这些私有属性:
let speak = Symbol('speak')
class Person {
[speak]() {
console.log('say Hi')
}
}
下面这几种访问都获取不到 speak 属性:
let p = new Person()
Object.keys(p) // []
Object.getOwnPropertyNames(p) // []
for(let key in p) console.log(key) // <empty>
但 Symbol 只能隐藏这些函数,并不能阻止未授权访问。 仍然可以通过 Object.getOwnPerpertySymbols(), Reflect.ownKeys(p) 来枚举到 speak 属性。
BigInt
什么是BigInt?
BigInt类型是 JavaScript 中的一个基础的数值类型,可以用任意精度表示整数。使用 BigInt,您可以安全地存储和操作大整数,甚至可以超过数字的安全整数限制。BigInt 是通过在整数末尾附加n或调用构造函数来创建的。
为什么需要BigInt?
Number类型只能安全的支持-9007199254740991(-(2^53-1)) 和 9007199254740991(2^53-1)之间的整数,任何超过这个范围的数值都会失去精度;而 BigInt 可以解决这个问题
console.log(9007199254740999) //9007199254741000 console.log(9007199254740993===9007199254740992) //true
从上面的代码,可以看到当数值超过 Number 数据类型支持的安全范围值时,将会被四舍五入,从而导致精度缺失的问题
如何创建并使用BigInt?
在整数的末尾追加n
console.log(9007199254740999n); //9007199254740999
调用BigInt()构造函数
let bigInt = BigInt("9007199254740999"); //传递给BigInt()的参数将自动转换为BigInt:
console.log(bigInt); //9007199254740999n