js中的数据类型
原始类型,对象类型
-
7种基本数据类型
- boolean
- null
- undefined
- number
- NaN
- Infinity
- string
- symbol
- static Symbol
- Symbol.prototype
- bigint
-
1种引用类型
+ 标准普通对象 object
+ 标准特殊对象对象 Array/RegExp/Date/Error/ArrayBuffer/DataView/Set/Map…
+ 非标准特殊对象 Number/String/Boolean/BigInt…
+ 可调用对象 「实现了call方法」 function
数据类型检测
- typeof 检测数据类型的逻辑运算符
- instanceof 检测是否为某个类型
- constructor 检测构造函数
- Object.prototope.tostring.call 检测数据类型
- Array.isArray isNaN…
typeof
- typeof [value] 返回当前值的数据类型
- 返回的结果都是字符串
- 局限性
- typeof null => “object”
- typeof 不能细分对象类型(检测普通对象或者数组对象都是object)
- 除可调用对象「(函数)实现了call方法」会返回’function’「不论是箭头函数还是构造函数、还是生成器函数、普通函数」,其余的都是Object
- 检测一个未被声明的变量不会报错,直接返回undefined
- typeof的原理
- 所以的数据数据值在计算机中存储的都是按照‘二进制’存储的
- null 000000
- 对象都是以 000 开头
- undefined -2^30 存储
- 数字 整数是1存储 浮点数是010
- 字符串是 100
- 布尔 是110
- typeof 在检测的时候, GetValue(val)「C++内部提供的方法」 是按照计算机存储的二进制的值来检测的
把其他类型转「原始值」 转换换成对象 Object([value])
-
把其他类型转换成数字
- Number([value])
- 一般是隐式转换「数学运算,isNaN,==比较…」
- 字符串中必须保证都是有效数字才会转换数字,否则都是NaN
- 布尔=> 数字 true=>1 false=> 0
- null => 0
- undefined=>NaN
- symbol=> 报错 不支持转换
- Bigint => 正常转换
- 对象遵循Symbol.toPrimitive/ValueOf/toString/number
- parseInt/parseFloat
- 首先会把value变成字符串,从字符串左侧第一个字符串查找,直到找到一个非有效数字字符为止,把找到的结果转换成数字,一个都没找到,结果就是NaN「parseFloat多识别一个小数点」
- Number([value])
-
把其他类型转换成字符串
- 原始值直接用引号包起来,「bigint会去掉n」;除对象转换为字符串是比较特殊的
- toString「排除Object.prototype.toString(检测数据类型)」
- 字符串/模版字符串拼接「加号在js中除了数字运算还有字符串拼接」
-
把其他类型转换成布尔
- 0 NaN null undefined 空字符串 转换为不二都是false
- Boolean(Value)
- !!Value
- !Value 转换成布尔类型取反
- 条件判断 例如if(value){}
- A||B A&&B
- isNaN 是否不是一个有效数字 false为有效 true为无效
-
不是所有对象都是字符串拼接
- 先去调取对象的Symbol.toPrimitive 属性,如果没有这个属性
- 再去调取对象的valueOf 获取原始值,如果不是原始值
- 再去调取对象得到toString转换为字符串「如果是想转换为数字,则还会调用Number处理」
把其他数据类型转换为数字的方法
- 强转换 (基于底层机制转换的)Number([value])
- 一些隐式转换都是基于Number 完成的
- isNaN(‘12px’) 先把其他类型值转换为数字再检测
- 数学运算 ‘12px’ - 13
- 字符串 == 数字 两个等于号比较很多时候也是要把其他值转换为数字
- …
- 弱转换(基于一些额外的方法转换)parseInt([value])/ parseint([value])
- 一些隐式转换都是基于Number 完成的
typeof number // ""number"
typeof true // "boolean"
typeof 'number' // "string"
typrof null "object"
typeof undefined // "undefined"
typeof Symbol('1') // "symbol"
typeof Bigint('1') // "bigint"
typeof {} // "object"
typeof [] // "object"
typeof function (){} "function"
let a = typeof typeof typeof [12,23]
console.log(a) // => "string" 自右向左
Symbol
获取对象中symbol值key可以使用 Object.getOwnPropertySymbol(obj) // 可以获取到obj上面的所有以symbol值key的属性
- 常见使用场景
- 给对象设置唯一的属性
- 在vuex/redux中做行为派发的时候 统一管理派发的行为标识,标识的值可以是唯一的
- 本身提供很多方法可以使用(主要的)
- Symbol.hasInstance
- Symbol.toPrimitive
- Symbol.toStringTag
- Symbol.iterator
- Symbol.isConcatSpreadable
- Symbol.match
- …
bigint
在数字的后面加个n就是Bigint类型值
NaN
- 与谁都不等 六亲不认 包括本身
- 如何判断是否为有效数组 isNaN(值) // 是否不是有效数字 是有效数组返回false 否则返回true
let res = parseFloat('left:200px');
if(res===200){
alert(200)
}else if(res===NaN) {
alert(NaN)
}else if(typeof res ==='number') {
alert('number')
}else { // "Invalid Number"
alert('Invalid Number')
}
// parseInt 处理的值是字符串,从字符串的左侧开始查找有效数字字符(遇到非有效数字字符则停止查找)=> 如果 处理的值不是字符串,需要先转换为字符串然后在开始查找接口
parseInt('') // NaN
Number('') // 0
isNaN('') // 先把''转换为数字(隐式Number) isNaN(0) false
parseInt(null) // parseInt('null') NaN
Number(null) // 0
isNaN(null) // isNaN(0) fasle
parseInt('12px') // 12
Number('12px') // NaN
isNaN('12px') // isNaN(NaN) fasle
parseFloat('1.6px')+parseInt("1.2px") +typeof parseInt(null); // 1.6+1 + 'number'
isNaN(Number(!!Number(parseInt('0.8')))) // 0 => false => 0 =>false
typeof !parseInt(null) + !isNaN(null) // 'boolean' + true =>booleantrue
[] == true // 转换为数字 Number([]) => Number('')=> 0 ==1 => false
Infinity === Infinity // true
Infinity === -Infinity // false
let reslut = 10+false +undefined + [] + 'Tencent' + null + true + {};
// 10 + 0 10
// 10 +undefined NaN
// 'NaN' + 'Tencent' + null 'NaNTencentnulltrue[object Object]'
// [] 转换为数字 是先ValueOf() => 再toString() => 转换成字符串''=>Number('') => 0
// 对象的tostring() 是转换成字符串和检测数据类型的
{} + 10 // 代码块 与 正10 =>10
10 + {} // 10[object Object]
({})+ 10 // [object Object]10
[] + 10 || 10 + [] // 调用toString() '' + 10 => 10
{} + 10 + {} // [object Object]10[object Object]
[] + {} // [object Object]
!(+[])+[]+![] // => true+''+false truefalse
{} + [] // 0
+{} +[] // => '[object Object]' + 0 => NaN
[]==0 // => '' == 0 => true
==,===区别
== 两边值类型不同的时候,要先进行类型转换,再比较
=== 不做类型转换,类型不同的一定不等.
==
和 ===
的规则如下:
===具体比较规则如下:
- 1、如果类型不同,就[不相等]
- 2、如果两个都是数值,并且是同一个值,那么[相等];(!例外)的是,如果其中至少一个是NaN,那么[不相等].(判断一个值是否是NaN,只能用isNaN()来判断)
- 3、如果两个都是字符串,每个位置的字符都一样,那么[相等];否则[不相等].
- 4、如果两个值都是true,或者都是false,那么[相等].
- 5、如果两个值都引用同一个对象或函数,那么[相等];否则[不相等].
- 6、如果两个值都是null,或者都是undefined,那么[相等].
==具体比较规则如下:
- 1、如果两个值类型相同,进行 === 比较,跟上面===一样
- 2、如果两个值类型不同,他们可能相等.根据下面规则进行类型转换再比较:
- a、如果一个是null、一个是undefined,那么[相等].
- b、如果一个是字符串,一个是数值,把字符串转换成数值再进行比较.
- c、如果任一值是 true,把它转换成 1 再比较;如果任一值是 false,把它转换成 0 再比较.
- d、如果一个是对象,另一个是数值或字符串,把对象转换成基础类型的值再比较.对象转换成基础类型,利用它的toString或者valueOf方法,js核心内置类,会先valueOf再toString;
- e、任何其他组合(array数组等),都[不相等].