js中基本类型 以及其转换规则
原始值类型引用数据类型,8种基本数据类型,容易被忽视的BigInt
原始值数据类型 | 各种类型之间的相互转换 |
---|---|
Number | Nuber(null) // 0 Number(undefied) // NaN Number([]) // 0 Number([0]) // 0 Number([1]) // 1 Number({}) -> NaN Number("12px") -> NaN Number("1.1e+21") |
String | String(null) // 'null' String(undefined) // 'undefined' String([]) // '' String({}) // '[object Object]' String([1,null,2,undefined,3]) // String(11e20) // "1.1e+21" |
Boolean | 有2种情况会隐式转换为布尔 1. 逻辑运算:与或非(! && !! || ) 2. 条件判断 if() {} / switch () 重点:有6种情况被称为falsy : NaN 、undefined、null 、0 、""、false (注意:这3种特殊的情况为true "false" 、 " " 、"0" ) |
Null | |
Undefined | |
Symbol | |
Bigint | BigInt数据类型的目的是比Number数据类型支持的范围更大的整数值 |
Object |
这里就null
与undefined
2种特殊的数据类型,做下解释:
类型 | 定义: | 用途 | 与其他类型值的转换 |
---|---|---|---|
null | 代表“空值”,代表一个空对象指针, 使用 typeof 运算得到 "object" ,所以可以认为它是一个特殊的对象值。 | 1.作为原型链的终 点用户定义参数的默认值, 表示为对象类型 | null == null //true null == undefined //true null == 0 // false null == false //false null == [] //false null == {} // false |
undefined | 声明了一个变量但并未为 该变量赋值,此变量的值默认为undefined | 1. 声明一个变量但是不赋值, 默认值为undefed 2.函数没有没有return值,默认为undefined 3.调用函数时,没有传参数,默认值为undefined 4.对象的某个属性没有赋值,默认值为undefied | undefined == undefined // true undefined == null //true dundefined == 0 //false undefined == false // false undefined == [] //false undefined == {} //false |
结论:null与undefined
除与自己以及彼此宽松相等
外其他的都不宽松相等。
js中常见的隐式转换场景
1. if
条件判断
if(xxx){};
switch(xxx){
case 1:
break;
default;
}
一般条件判断时,会将条件 xxx
转换成布尔类型,再进行等式2边的判断
2. ==
比较操作 >= <=
等
==
比较操作:如果表达式2边的数据类型不一样,首先会隐式转换为相同的类型,然后再做比较
>= <=
都为字符串时不会将2边的表达式转换为 Number类型,eg:"2" > "10"
// true
- 对象 == 字符串 (此时会先将对象转换成字符串再进行比较)
- null == undefined
true
注意:[如果此时是3个等号是不相等的,但是null、undefined和其他的值都不相等] - NaN == NaN
true
//此时如果是===
则是不相等的 - Symbol == Symbol
false
- 其余的情况 【例如:对象 == 数字 、字符串 == 布尔 ...】都要先转换成数字,再进行比较 举个栗子:
![] == false // true
[] == false // true
为什么会出现 ![] 与 [] 都 == true呢?
![] === false 转换过程为 Number(!Boolean([])) == Number(false) 2. [] === false 转换过程为 Number([]) == Number(false)
3. 加号 +
与 减号 -
+
除了会隐式转换为Number类型外,还有字符串拼接
的职能
常见的转换为规则:
表达式 | 输出 |
---|---|
1 + 1 | 2 |
1 + "1" | "11" |
1 - "1" | 0 |
-
常见的
n++
与++n
的区别 -
+n 转换为数字
-
++n 转换为数字然后累加1
-
n++ 转换为数字然后累加1
来3个栗子:
CASE1: 下面的3个表达式 i++ 、i += 1; i = i +1 相同吗?
表达式 | |
---|---|
i++ | 转换成数字之后累加1 |
i += 1 | 有可能是字符串拼接 |
i = i +1 | 有可能是字符串拼接 |
因此:3个表达式是不相等的
,且只有 i +=1 与 i = i +1 是相等的
CASE2: + 号有一边出现 对象
let n = 10;
{} + n // 10 ,会将 {} 当做代码快,不参与运算,运算的只有 +n
n + {} // "10[object Object]" 字符串拼接
CASE3重点
: 不是所有的对象都是直接转换成字符串然后拼接,而是
- 先去调取对象的
Symbol.toPromitive
属性值,如果没有这个属性 - 再去调用对象的
valueOf
获取原始值,如果不是原始值 - 再去调用对象的
toString
转换为字符串 【如果是想转换为数字,则还会调用Number处理】
console.log(10 + [10,20]) // 1010,20 字符串拼接
// 1.[10,20][Symbol.toPromitive]
// 2.[10,20].valueOf() 存在
// 3.最终转换为字符串
来2个测试题: 下面表达式输出什么?
let i = 10;
console.log(5 + (i++)) // 15 ,后置 ++ 第一次不生效
console.log(5 + (++i)) // 17 ,由于上一次的后置 ++ 此时 i为11 再前置 ++,此时i为 12
console.log({} + i) ; // 12 , {}会当做为代码块
console.log(i + {}); //"12[object Object]"
如何将 10 + {a: 10},变为20
let obj ={
a:10,
[Symbol.toPrimitive](hint){
console.log("hint",hint) // "default"、'string'、'number'
return this.a;
}
}
console.log(10+obj) //使用CASE3的几个api或者setter都可以实现
有哪些内置对象类型
对象类型 | 引用数据类型 |
---|---|
标准对象类型:Object、Array、RegExp、Date、Math、Error、ArrayBuffer、DataView、Set、Map | |
非标准特殊对象 Number、String、Boolean、Symbol、Bigint。。。基于构造函数或则object创造出来的原始值对象类型的格式信息,类型属于对象类型 | |
可调用的执行对象 :实现了可调用对象函数 function |
数据类型检测方式有哪些
3种检测数据类型的方法
方法 | 函数 |
---|---|
typeof | 判断简单的数据类型 number、string、undefined、symbol、function 无论用typeof检测的是什么,返回的都是字符串 typeof typeof typeof [1,2,3] 返回的是字符串string 缺点:无法区分具体的引用类型 |
instanceOf | |
Object.prototype.toStirng.call(value) |
使用typeof一览表
- typeof底层机制就是判断这些二进制,000开始的都是对象,排除函数
Undefined | 'undefined' |
---|---|
Null | 'object' |
Boolean | 'boolean' |
String | "string" |
Symbol | "symbol" |
Object(ordinary and does not implement[[call]]) | "object" |
Ojbect(stardard exotic and does not implement[[call]]) | "object" |
Object(implement[[call]]) | "funciton" |
Object(non-stardard exotic and does not implement[[call]]) | implement-defined. Must not be 'undefined'、‘boolean’、'function'、'number'、'symbol'、or 'string' |
未被申明的变量 | undefined |
typeof 未被申明的变量不会报错
计算机科学:计算机原理,进制转换,计算机网络,数据结构和算法
000 | 对象 |
---|---|
1 | 整数 |
010 | 浮点数 |
100 | 字符串 |
110 | 布尔 |
000 | 对象 |
000000 | null |
-2^30 | undefined |
特点1:
typeof null -> "object"
// 原因就是因为null在计算机中存储的就是 000000
// 检测对象数据类型,除了可执行对象[函数:能够调用call方法的 & 普通函数、构造函数、箭头函数、生成器函数]
// 检测出来的 'function',其余都是 'object',如:typeof new RegExp(/b/g) 输出 'object'
特点2:
typeof 对象 -> "object" && typeof 函数 -> "function"
特点3:typeof 未被申明的变量 -> "unfedined":如何利用此特性(场景举例:插件封装中的暴露API)
(function () {
let utils = {
};
// 这样写有什么问题? 如果不存在某个变量,可以用typeof来判断
if (typeof window !== 'undefined') window.utils = utils;
// common.js规范导出
if (typeof module == 'object' && typeof module.exports === 'object') moudule.exports = utils;
})()
// 只能针对浏览器
// utils.xxx()
快捷检测数字类型的方法
api | 作用 |
---|---|
Array.isArray() | 判断是否为数组 |
isNaN | 是否非数字 |
特殊的数据类型Symbol
数据类型如果获取?
- Symbol如何获取唯一值
let n = Symbol('AA');
let m = Symbol("AA");
console.log(n == m) //false
let key = Symbol();
let obj = {
[key]:100
}
console.log(obj[key]);
- Symbol有哪些常用api ?
Symbol.hasInstance
Symbol.iterator
Symbol.toPrimitive
Symbol.toStringTag
把其他类型【原始值类型】转换为对象 Object([value])
规则:原始值转换是直接用引号包起来 【bigint去掉n】 [除对象转换为字符串]
表达式 | |
---|---|
(Symbol()).toString() | "Symbol()" |
(10n).toString() | "10" |