Javascript

1.JavaScript有哪些类型

栈(先进后出;占据空间小、大小固定、属于被频繁使用的数据):原始数据类型 undefined、null、boolean、number、string、BigInt

堆(二叉树结构;占据空间大,大小不固定,存储在栈影响性能,把指针存在栈中,指针指向实体位置,取值通过栈值去堆中取值):引用类型 Object、Array、Function、Date、RegExp

集合类型:Map、Set

2.检测类型

typeof检测{}、[]、null都是object,NaN是number,检测其他都正确

instanceof无法检测原始数据类型,可以检测引用数据类型

construct都可以检测出来,前提是原型不能被修改,(2).construct === Number

Object.prototype.toString.call(值)也都可以检测出来,值是返回[object 对应的类型]

3检测数组

Object.prototype.toString.call(obj).slice(8,-1) === 'Array'

obj.__proto__ === Array.prototype

Array.isArray(obj)

obj instanceof Array

Array.prototype.isPrototypeOf(obj)

4其他值转成布尔值规则

undefined、null、false、+0、-0、NaN、“”是false,其他都是true

5||和&&

||是如果第一个值为真则返回第一个值,否则返回第二个值

&& 是如果第一个值为真则返回第二个值,否则返回第一个值

6 ==、===、Object.is区别

==会强制转换;===和Object.is不会强制转换,但Object.is特殊了-0和+0不相等、NaN和NaN是相等的

7JavaScript的包装类型

基本类型是没有属性和方法的,但是为了方便操作基本类型的值会隐式的将基本类型转为对象如字符串有.length获取长度,实际上执行了Object()包装成了Object,因此typeof new (false)也是Object类型

8.强制转换规则

在 JavaScript 中,使用 == 进行比较时,如果两个值的类型不同,JavaScript 会进行类型转换,但 不一定是转为布尔值。根据不同的类型,JavaScript 会按照不同的规则进行转换。这里的转换是通过 类型强制转换(type coercion)来完成的。

抽象相等比较 (==) 规则:

== 比较运算符在进行比较时会尝试将操作数转化为相同的类型,然后再进行比较。具体的规则如下:

1. 如果两个操作数是相同类型

  • 如果两个操作数的类型是相同的,直接进行比较。
    • 例如: 1 == 1 结果为 true'hello' == 'hello' 结果为 true

2. 如果操作数类型不同

a. 数字与字符串比较:

  • 字符串会转换为数字进行比较。
    • 例如: '1' == 1'1' 会被转换为数字 1,所以结果是 true

b. 布尔值与其他类型比较:

  • 布尔值会先被转换为数字true 会转为 1false 会转为 0
    • 例如: true == 1true 会被转换为 1,所以结果是 true
    • 例如: false == 0false 会被转换为 0,所以结果是 true

c. nullundefined 比较:

  • nullundefined 只与彼此相等,它们与其他任何值比较都会得到 false
    • 例如: null == undefined 结果是 true,而 null == 0undefined == 1 都是 false

d. 对象与基本类型比较:

  • 当比较对象和原始值(如字符串、数字等)时,JavaScript 会 调用对象的 toPrimitive() 方法,将对象转化为原始值(比如数字或字符串),然后进行比较。
    • 例如: [] == '' 结果是 true,因为 [] 会被转换为空字符串 ""
    • 例如: {} == '[object Object]' 结果是 false,因为对象无法直接与字符串进行比较,它会先转化为 [object Object]

3. 特殊情况:

  • NaN 与任何值的比较总是 false,包括 NaN == NaN,这是因为 NaN 是 JavaScript 中唯一不等于它自身的值。
    • 例如: NaN == NaN 结果是 false

总结:

  • == 比较会先检查两边的值类型是否相同,如果不同,JavaScript 会根据一定的规则进行转换,而不仅仅是转换为布尔值。转换的目标值取决于操作数的类型:
    • 数字与字符串会转换为数字进行比较。
    • 布尔值会转换为数字(true 为 1,false 为 0)。
    • nullundefined 只有与彼此相等。
    • 对象与其他类型进行比较时会先调用 toPrimitive 转换对象。

toPrimitive介绍:

ToPrimitive方法,这是 JavaScript 中每个值隐含的自带的方法,用来将值 (无论是基本类型值还是对象)转换为基本类型值。如果值为基本类型,则直接返回值本身;如果值为对象,则如下
/**
* @obj 需要转换的对象
* @type 期望的结果类型
*/
ToPrimitive(obj,type)

type的值为number或者string

(1)当typenumber时规则如下:

  • 调用objvalueOf方法,如果为原始值,则返回,否则下一步;
  • 调用objtoString方法,后续同上;
  • 抛出TypeError 异常。

(2)当typestring时规则如下:

  • 调用objtoString方法,如果为原始值,则返回,否则下一步;
  • 调用objvalueOf方法,后续同上;
  • 抛出TypeError 异常。

可以看出两者的主要区别在于调用toStringvalueOf的先后顺序。默认情况下:

  • 如果对象为 Date 对象,则type默认为string
  • 其他情况下,type默认为number

总结上面的规则,对于 Date 以外的对象,转换为基本类型的大概规则可以概括为一个函数:

var objToNumber = value => Number(value.valueOf().toString())
objToNumber([]) === 0
objToNumber({}) === NaN

而 JavaScript 中的隐式类型转换主要发生在+、-、*、/以及==、>、<这些运算符之间。而这些运算符只能操作基本类型值,所以在进行这些运算前的第一步就是将两边的值用ToPrimitive转换成基本类型,再进行操作。

以下是基本类型的值在不同操作符的情况下隐式转换的规则 (对于对象,其会被ToPrimitive转换成基本类型,所以最终还是要应用基本类型转换规则):
  1.+操作符+操作符的两边有至少一个string类型变量时,两边的变量都会被隐式转换为字符串;其他情况下两边的变量都会被转换为数字。

1 + '23' // '123'
 1 + false // 1 
 1 + Symbol() // Uncaught TypeError: Cannot convert a Symbol value to a number
 '1' + false // '1false'
 false + true // 1
  1. -*\操作符NaN也是一个数字
3 == true // false, 3 转为number为3,true转为number为1
'0' == false //true, '0'转为number为0,false转为number为0
'0' == 0 // '0'转为number为0
  1. 对于==操作符操作符两边的值都尽量转成number
3 == true // false, 3 转为number为3,true转为number为1
'0' == false //true, '0'转为number为0,false转为number为0
'0' == 0 // '0'转为number为0
  1. 对于<>比较符如果两边都是字符串,则比较字母表顺序:
'ca' < 'bd' // false
'a' < 'b' // true

  其他情况下,转换为数字再比较:

'12' < 13 // true
false > -1 // true

以上说的是基本类型的隐式转换,而对象会被ToPrimitive转换为基本类型再进行转换:

var a = {}
a > 2 // false

对比过程如下

a.valueOf() // {}, 上面提到过,ToPrimitive默认type为number,所以先valueOf,结果还是个对象,下一步
a.toString() // "[object Object]",现在是一个字符串了
Number(a.toString()) // NaN,根据上面 < 和 > 操作符的规则,要转换成数字
NaN > 2 //false,得出比较结果

又比如

var a = {name:'Jack'}
var b = {age: 18}
a + b // "[object Object][object Object]"

运算过程如下

a.valueOf() // {},上面提到过,ToPrimitive默认type为number,所以先valueOf,结果还是个对象,下一步
a.toString() // "[object Object]"
b.valueOf() // 同理
b.toString() // "[object Object]"
a + b // "[object Object][object Object]"

 

posted on   ChoZ  阅读(3)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示