数据类型
number、string、boolean、null、undefined、symbol、bigInt、object(8)
- 弱类型语言如何理解?
声明变量的时候没有预先确定变量的类型,
变量类型在赋值时由值的类型确定。上一秒可能Number类型,下一秒就变成String是很正常的情况。过程中有时会发生强制类型转换。
基本数据类型
undefined
- undefined类型的值为undefined
- 当使用var或let声明了变量却没初始化时 相当于给变量赋值undefined
-
注意区别undefined和未定义
-
输出一个未声明变量的值 会导致报错
-
对未声明变量的唯一操作是使用typeof
let msg; console.log(msg); // undefined console.log(typeof no); // undefined console.log(no); // 报错 Uncaught ReferenceError: no is not definedlet msg; if(msg) { console.log('1'); } if(!msg) { console.log('2'); // 输出 } if(no) { console.log('3'); // 报错 }
Null
- null类型同undefined 值为null。逻辑上来说 null值表示一个空对象指针 所以typeof null为"object"
- 在定义将来要保存对象值的变量时 建议使用null初始化。这样后续只要检查是否为null就可以知道此变量是否在后来被重新赋予了一个对象的引用
-
检测null
let message = null; let age; if(message) { console.log('1'); } if(!message) { console.log('2'); // 输出 } if(age) { console.log('3'); } if(!age) { console.log('4'); // 输出 }
Number
- 正数/负数/零/小数
- NaN和NaN本身都不相等
- NaN(not a number) 不是一个有效数字 但是它却属于number类型
- 可以使用isNaN([value])检测一个值是否为非有效数组 false为有效数字。如果[value]不是数字类型的值。则会基于Number([value])进行隐式类型转换
isNaN
isNaN(10); // false 为有效数字
isNaN('AA'); // true
isNaN('10'); // false 为有效数字 使用Number()转为10
isNaN('10px'); // true
- 在使用isNaN进行检测时,会先验证检测的值是否为数字类型,如果不是,会先基于Number()转换为数字类型再检测
把其他数据类型转换为number
- Number([value])把其他数据类型转换为number数据类型
-
字符串转为数字:空字符串是0
如果字符串中出现任意一个非有效数字字符 第一个点除外 结果都是NaNNumber("10px"); // NaN Number("10.5"); // 10.5 Number("10px"); // NaN Number("10.5.5"); // NaN -
布尔转为数字
Number(true); // 1 Number(false); // 0 Number(null); // 0 Number(undefined); // NaN Number(undefined); // -
引用数据类型转换为数字:首先基于toString()转为字符串 在基于Number()转为数字
数组才可能是数字
Number([]); // 0 Number([12]); // 12 Number([12,23]); // NaN Number({}); // NaN [].toString() // ''空数组转为字符串为空字符串 空字符串转为数字为0
-
parseInt/parseFloat([val], [进制]):从左到右依次查找有效数字字符,知道遇到非有效数字字符,停止查找
-
进行==比较时,可能出现吧其他类型转换为数字
String
所有用单引号、双引号、反引号包起来的都是字符串
把其他类型转为String
-
(val).toString()
-
字符串拼接
只有加法可能存在字符串拼接。其他四则运算为数学运算
console.log('10' + 10); // '1010' console.log('10' - 10); // 0 Number('10') => 10 - 10 = 0 console.log('10px' - 10); // 先使用Number()为NaN => NaN-10 = NaNlet a = 10 + null + true + [] + undefined + '珠峰' + null + [] + 10 + false; /* 10 + null -> 10 + 0 = 10 10 + true -> 10 + 1 = 11 11 + [] -> 11 + [].toString() => 10 + '' = '11' '11' + undefined + '珠峰' + null + [] + 10 + false' = '11undefined珠峰null10false' */不管是变的过程中还是之后 只要遇到字符串直接拼接
- null和undefined禁止直接toString() 结果为'null'和'undefined'
- 普通对象.toString()的结果是"[object Object]" =>
Object.prototype.toString()不是用来转换为字符串的,而是用来检测数据类型的
Boolean
把其它类型转换为布尔类型
只有0、NaN、' '、null、undefined五个值为false 其余转为boolean都为true
-
Boolean([val])
-
!/!!
!:取反(先转为布尔 然后取反)
!!:取反再取反,相当于转换为布尔 <==> Boolean
-
条件判断
如果条件只是一个值 先将这个值转为布尔类型 然后验证真假
if(1) { console.log('hh'); // 输出 } if('3px' + 3) { // Boolean('3px3') => true console.log('hh2'); // 输出 } if('3px' - 3) { // Boolean(NaN-3) => Boolean(NaN) => false console.log('hh3'); }null/undefined
null和undefined都代表的没有
null:意料之中(开始不知道 手动设置为null 后期再赋值)
undefined:意料之外(创建变量但未初始化 默认值为undefined)
引用数据类型
Object
{[key]: [value],...} 任何一个对象都是有零到多组键值对(属性名: 属性值)组成的(并且属性名不能重复)
- 获取属性名对应的属性值
对象.属性名
对象[属性名] 属性名是数字或者字符串格式的
如果当前属性名不存在 默认的属性值是undefined
数据类型检测
- typeof:检测数据类型的运算符
- instanceof:检测当前实例是否隶属于某个类
- constructor:基于构造函数检测数据类型(也是基于类的方式)
- Object.prototype.toString.call():检测数据类型最好的方法
typeof
基于typeof检测的结果为String
console.log(typeof 1); // 'number'
console.log(typeof null); // 'object'
console.log(typeof typeof typeof []); // typeof [] => "object" --> typeof "string" => "string" 只要两个及两个typeof以上同时检测 最后结果必然是"string"
局限性:
- typeof null => "object" 但是null并不是对象
- typeof无法细分当前是普通对象还是数组对象
数据类型practice
例1:
!!" " + !!"" - !!false || console.log('z')
!!为转Boolean;Boolean(" ")为true;Boolean( "" )为false