js

js变量类型的细节

变量类型转换与判别规则全解析

Posted by AzirKxs on 2022-10-17
Estimated Reading Time 6 Minutes
Words 1.5k In Total
Viewed Times

[] == ![] !? 浅析JS的类型系统和隐式类型转换 - 掘金 (juejin.cn)

(12条消息) 比较运算符 == 的类型转换规则_zhouhao620的博客-CSDN博客

(12条消息) valueOf()函数_不吃饭会饿的博客-CSDN博客_valueof

javascript之类型的细节

javascript的变量转换

String的类型转换

显示转换
  • 使用toString方法
  • 调用String函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
let str = String(123)
let num = (123).toString()
console.log(typeof str)//string
console.log(typeof num)//string
//基本类型转换
String(4) // "4"
String(false) // "false"
String(true) // "true"
String(null) // "null"
String(undefined) // "undefined"
String(Symbol('s')) // "Symbol(s)"
//引用类型的转换
String({ a: 2 }) // "[object Object]"
String([1, 2]) // "1,2"
String(/reg/g) // "/reg/g"
//object类型在强制转换为string类型的时候,
// 实际是调用了该类型原型上的toString方法,
// 而Object的各个子类型基本都重写了toString方法
// 所以在进行String操作的时候表现有差异

//String与toString都是将别的类型转换为String类型,但是toString无法转换null和undefined,会报错
隐式转换
  • 一个字符串和别的数值类型进行+操作
  • 某些函数的执行也会自动将参数转换成字符串类型例如console.log()
1
2
3
4
5
let str = "123"
let num = 123
let unit = str+num
console.log(unit)//123123
console.log(typeof unit)//string

Number的类型转换

显示转换
  • 使用Number函数转换
隐式转换
  • 除了+运算,在别的算数运算中,都会将其他类型转换成数字类型来处理
转换规则

image-20221013142706917

1
2
3
4
5
6
7
8
9
10
console.log(Number('123hello123'))//NaN
console.log(Number('123'))//123
console.log(Number(''))//0
console.log(Number(true))//1
console.log(Number(false))//0
console.log(Number({}))//NaN
console.log(Number(null))//0
console.log(Number(undefined))//NaN
console.log(Number([]))//0
Number(Symbol('s'))// TypeError...

boolean的类型转换

转换规则

image-20221013142857983

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//非空的字符串总是true
console.log(Boolean('true'))//true
console.log(Boolean('false'))//true
console.log(Boolean('0'))//true
console.log(Boolean([]))//true
console.log(Boolean({}))
console.log(Boolean(''))//false
console.log(Boolean(null))//false
console.log(Boolean(undefined))//false
console.log(Boolean(0))//false
console.log(Boolean(NaN))//false

//false值的七种情况
//false, undefined, null, NaN, 0(包括+0,-0), 空字符串,0n(BigInt)

ToPrimitive

当对象需要转换成基本数据类型时,就会执行ToPrimitive过程

ToPrimitive过程先回检查对象是否存在valueOf方法,如果存在并且valueOf返回基本类型的值,则使用该值进行强制类型转换,如果没有,则使用toString方法返回的值进行强制类型转换。

在+运算中,如果其中一个操作数是字符串;或者其中一个操作数是对象,且可以通过ToPrimitive操作转换为字符串,则执行字符串连接操作;其他情况执行加法操作。

1
2
3
4
5
6
console.log(1+true)//2
console.log(1+{})//1[object Object]
console.log(1+[1,2])
console.log(1+[]) //1
console.log(1+[1,2])//11,2
console.log({} + [])//[object Object]

如果在浏览器控制台这样输入则会有不同的表现,那是因为{}被解析成了代码块,因此只是将[]转换成了number
image-20221018195924401

==和===

==和===的区别

===比==更加严格,==在比较两个数据类型不同的值的时候,会进行自动数据类型转换,而===在比较两个数据类型不同的值的时候,会直接返回false

1
2
3
4
console.log(1=='1')//true
console.log(1 == true)//true
console.log(0 == false)//true
console.log(1==='1')//false

==的一些特殊表现

  • NaN不等于NaN
1
2
3
console.log(NaN == NaN)//false
console.log(null == null)//true
console.log(undefined == undefined)//true
  • null == 0为false
1
2
3
console.log(Number(null) == 0) //true
console.log(null == 0) //false
console.log(null>=0) //true
  • undefined == null 为true
1
console.log(null == undefined)
  • 以及上面探讨过的
1
2
3
4
5
true + true === 2           // true
false === 0 // false
false + false === 0 // true
{} + [] === 0 // true
[] + {} === 0 // false

== 的类型转换规则

对于数字和字符串的抽象比较,将字符串进行ToNumber操作后再进行比较

对于布尔值和其他类型的比较,将其布尔类型进行ToNumber操作后再进行比较

对于对象和基础类型的比较,将对象进行ToPrimitive操作后在进行比较

对象之间的比较,引用同一个对象则为true,否则为false

valueOf

valueOf()函数返回指定对象的原始值。

JavaScript的许多内置对象都重写了该函数,以实现更适合自身的功能需要。因此,不同类型对象的valueOf()方法的返回值和返回值类型均可能不同。

对象 返回值
Array 数组实例对象。
Boolean 布尔值。
Date 以毫秒数存储的时间值,从 UTC 1970 年 1 月 1 日午夜开始计算。
Function 函数本身。
Number 数字值。
Object 对象本身。这是默认设置。
String 字符串值。
1
2
3
4
5
let str = new String(123)
console.log(str) //String {'123'}
console.log(typeof str)//object
console.log(str.valueOf())//123
console.log(typeof str.valueOf())//string

类型检测

typeof

typeof用于检测类型,但是对于引用类型来说又有一定的局限性,无法区分object类型的子类型

先看两几个例子

1
2
3
4
5
6
console.log(typeof [] === typeof {})//true
console.log(typeof null)//object
console.log(typeof NaN)//number
console.log(typeof Infinity)//number
console.log(typeof document.addEventListener)//object
console.log(typeof new String(123))//object

typeof的返回值有number,string,boolean,object,undefined,function,symbol

  • 对于number,string,boolean,symbol返回对应的结果

  • 对于对象,数组,null返回object

  • 对于函数返回function

  • 对于定义没有赋值的变量返回undefined

Object.prototype.toString

可以通过Object.prototype.toString来检测每个对象的类型,而不是单纯的返回object

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Obejct.prototype.toString.call(undefined);
// "[object Undefined]"

Obejct.prototype.toString.call(null);
// "[object Null]"

Obejct.prototype.toString.call(true);
// "[object Boolean]"

Obejct.prototype.toString.call('');
/// "[object String]"

Obejct.prototype.toString.call(123);
// "[object Number]"

Obejct.prototype.toString.call([]);
// "[object Array]"

Obejct.prototype.toString.call({});
// "[object Object]"

使用该种方式无法鉴别基本数据类型还是包装类型,返回值都为[Object xxx]

1
2
3
4
5
6
var num = 42
var numObj = new Number(42)
typeof num // number
typeof numObj // object
Object.prototype.toString.call(num) // "[object Number]"
Object.prototype.toString.call(numObj) // "[object Number]"

如果这篇文章对你有帮助,可以bilibili关注一波 ~ !此外,如果你觉得本人的文章侵犯了你的著作权,请联系我删除~谢谢!