大厂前端面试题:[]==![] 返回什么?true or false? why?

在聊上述问题前咱们先来讲讲js的数据类型转换,前段时间咱们学习了js中的类型判断,我们知道了如何去判断js中的数据类型,那么,在这么多种数据类型中,它们之间又是如何进行相互转换的呢?今天,小编就带大家来聊一聊js中的数据类型转换。

一、原始值转原始值 ----显示转换

原始值之间的转换(用Boolean、Number、String)

1.原始值转布尔 Boolean(xx)

2.原始值转数字 Number(xx)

3.原始值转字符串 String(xx)

4.原始值转对象 new(xx)

image-20240521103612260.png

二、对象转原始值:

在js中,当咱们需要将对象转换为原始值的时候,v8引擎则会调用对象的ToPrimitive()方法来实现

ToPrimitive()

主要作用是将一个JavaScript值转换为原始类型(primitive value),即字符串(String)、数字(Number)、布尔值(Boolean)、null、undefined或Symbol中的任意一种。这一转换过程在某些情况下自动发生,例如当值需要进行数学运算、比较或者作为字符串拼接的一部分时。

具体来说,ToPrimitive() 方法根据上下文可以选择使用哪种转换方式(数值转换或字符串转换):

  • 数值上下文(number hint):当值用于数学运算或需要被解释为数值时,比如加减乘除等操作,这时倾向于转换为数值类型。
  • 字符串上下文(string hint):当值用于需要字符串表示的场景时,如与字符串相连或作为模板字符串的一部分,这时倾向于转换为字符串类型。

如果被转换的对象是一个对象(而不是原始类型),ToPrimitive() 还会尝试调用对象上的 valueOf() 方法和 toString() 方法(按此顺序),直到得到一个原始值。对象可以通过定义自己的 valueOf()toString() 方法来控制这一转换过程。如果这两个方法都未返回原始值或抛出错误,则会抛出TypeError异常。

这是官方文档给出的说明和解释:

image-20240521105654039.png

我给大家来解释概括以下ToPrimitive()方法的原理哈:

ToPrimitive()方法规则

如果是想把对象转换为字符串类型则会先执行toString()方法,如果是想把对象转换为数字类型则会先执行valueOf()方法

ToPrimitive(obj,String)==>String(obj)

  1. 如果接收到的参数是原始值,则直接返回该值
  2. 否则,调用toString()方法,如果得到原始值,返回
  3. 否则,调用valueOf()方法,如果得到原始值,返回
  4. 报错

ToPrimitive(obj,Number)==>String(obj)

  1. 如果接收到的参数是原始值,则直接返回该值
  2. 否则,调用valueOf()方法,如果得到原始值,返回
  3. 否则,调用toString()方法,如果得到原始值,返回
  4. 报错

我给大家详细说一下toString()方法和value()方法:

toString()方法:

- 所有对象转原始值都会调用toString()

1.{}.toString() 得到由"[object 和 class 和]"组成的字符串

2.[].toString() 返回由数组内部元素以逗号拼接的字符串

3.xx.toString() 返回字符串字面量

image-20240521111035051.png

valueOf()方法:

——仅限于包装类对象

image-20240521111641638.png

对象转布尔,一定是ture

let a = {};
let b = [];
if (a) { //Boolean()
    console.log('hello');
}
if (b) {
    console.log('hello');
}

输出:hello hello

可以看到,if (a)会将a转换为布尔值,Boolean(a),同时b也是,所以对象转布尔值都为true。

隐式转换

在js中,当不同类型的值相互操作时,会发生隐式类型转换。例如,当字符串和数字相加时,js会将数字转换为字符串以进行连接。

一元运算符+

案例一:

分析+"123"的结果

1.因为前面有一元运算符+,所以先执行ToNumber("123")

2.结果:+123——>123

所以输出结果就是123.

案例二:

分析+[]的结果:

  1. 因为前面有一元运算符+,所以先执行ToNumber([]) ,在js官方文档关于ToNumber()的解释是这样的:

image-20240521114414597.png

2.我给大家解释一下,就是当传入的参数为对象时,也就是表格最后一点,执行ToPerimitive([], Number)

3.根据上面给出的关于ToPerimitive([], Number)的执行步骤,先执行[].valueOf() ,但是valueOf只能只能转换包装类对象(即string、number、boolean),所以执行结果为[]

4.接着执行[].toString(),根据上述给出的结论([].toString() 返回由数组内部元素以逗号拼接的字符串),所以结果为” “

5.+” “就是将''转换为number类型,即Number(''),结果为0

所以输出结果为0.

二元运算符

v1+v2:

1.lprim =ToPrimitive(v1)

2.rprim =ToPrimitive(v2)

3.如果 lprim 或者 rprim 是字符串,那么就ToString(lprim)或者ToString(rprim)再拼接

4.否则,ToNumber(lprim) + ToNumber(rprim)

案例一:

分析1 + '1'的结果

  1. lprim = ToPrimitive(1) rprim = ToPrimitive('1')
  2. ToPrimitive(1):传入的参数为number类型,先调用1.valuoOf(),结果为1(1为number类型,为包装类),所以lprim = 1
  3. ToPrimitive('1'):传入的参数为string类型,先调用'1'.toString(),结果为'1',所以rprim = '1'
  4. 因为rprim 是字符串,所以执行ToString(1) + '1'
  5. '1' + '1' ==> '11',所以结果为'11'

结果:”11“

案例二:

分析null + 1的结果:

  1. lprim = ToPrimitive(null) rprim = ToPrimitive(1)
  2. ToPrimitive(null),根据给出的关于ToPrimitive()的js官方文档,结果为null,所以lprim = null
  3. ToPrimitive(1):传入的参数为number类型,先调用1.valuoOf(),结果为1(1为number类型,为包装类),所以rprim = 1
  4. 因为lprim 和 rprim 都不是字符串 ,所以执行ToNumber(null) + ToNumber(1) ,结果为0+1=1

结果:1

案例三

分析 [] + {}的结果:

  1. lprim = ToPrimitive([]) rprim = ToPrimitive({})
  2. 因为此时在两个对象中间有个运算符+,所以执行number类型的步骤,即先执行[].valueOf() + {}.valueOf(),结果为[]和{}
  3. 接着执行[].toString() + {}.toString,[].toString()的结果为”“, {}.toString的结果为[object Object]
  4. ""+ '[object Object]' ==> '[object Object]',所以结果为'[object Object]'

结果输出:'[object Object]'

关于 ==

image.png

例一:

分析1 == {}的结果:

  1. 根据给出的js官方文档,如果一个数为对象,另外一个数为number类型,执行1 == ToPrimitive({})(根据第八点和第九点)
  2. ToPrimitive({}):有个运算符==,所以执行number类型的步骤,即先执行{}.valueOf() ,结果为{},然后执行{}.toString(),结果为'[object Object]'
  3. 根据给出的js官方文档,如果一个数为字符串,另外一个数为number类型,执行1 == ToNumber('[object Object]')(根据第四点和第五点)
  4. ToNumber('[object Object]')的结果为NaN,即结果为 1 == NaN-->false

结果:false

最后咱们就可以来分析一下[] == ![]的结果:

  1. ![] 运算符会将空数组 [] 转换为布尔值。在js中,空数组被视为一个真值,原因:[]根据js官方文档,执行ToPrimitive([]),有个运算符==,所以执行number类型的步骤,即先执行[].valueOf() ,结果为[],然后执行[].toString(),所以结果为''
  2. !的执行步骤是先转换为布尔值再取反,Boolean('')为true,所以![]的结果为false
  3. 即[] == false,此时如果一个操作数是布尔值,另一个操作数不是布尔值,则会将布尔值转换为数字再进行比较。执行[] == ToNumber(false)(根据第六点和第七点),即[] == 0
  4. 接着执行ToPrimitive([]) == 0(根据第八点和第九点)
  5. ToPrimitive([]) :有个运算符==,所以执行number类型的步骤,即先执行[].valueOf() ,结果为[],然后执行[].toString(),结果为''
  6. 即'' == 0,接着执行ToNumber('') == 0(根据第四点和第五点)
  7. 即 0 == 0 --> true,所以结果为true

因此最终结果为true.

文章转自:https://juejin.cn/post/7370930879705301011

  • 19
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值