面试官:js只有一个toString吗

这两天我有个小伙伴二面面b站的时候被面试官问到了这个问题,觉得挺有意思的,分享给大家~

jstoString其实不止对象身上的toString方法,虽然传统上我们一般说的toString就是对象身上的,也就是Object.prototype.toString,但其实toString是有三种的

  1. {}.toString()返回由"[object"和class和']'组成的字符串
  2. [].toString()返回由数组内部元素以逗号拼接的字符串
  3. xx.toString()直接返回字符串字面量

Object.prototype.toString()

js官方:带注释的 ES5 --- Annotated ES5

对于普通对象来说,Object是构造函数,因此此时的toString就是构造函数原型身上的方法,而我们普通对象去寻找身上的属性就是先去构造函数显示具有的属性中去找,这个显示属性就是构造函数自身的属性,找不到时,就去自己自己的隐式原型身上找,而实例对象的隐式原型(__proto__)就是构造函数的显示原型(prototype),因此才能去调用这个toString,而这个toString的作用是用来判断数据类型的

既然是对象,那么就是输出[object Object]

数组也是对象,那数组调用这个toString,是否就是输出[object Array],我们来看下

哦嚯~,居然不是,是个空

注意:不是空字符串,就是空,因为空格也是字符串

如果数组构造函数Array身上没有写toString,那么这个输出结果一定不是空,而是[object Array],因为他会顺着原型链去找到对象身上的toString

这就是因为官方给数组原型身上已经打造了另一个toString,或者说是重写了个toString

[].toString()

没错!这就是因为数组身上的toString方法,数组里面有什么,就以字符串的方式返回出来

xx.toString

好了,既不是数组又不是对象,那么其余的类型就是这个版本的toString,也就是直接返回字符串字面量

那我写个函数函数表达式,看看这个值输出的字符串字面量长什么样子~

整个函数体都打上了引号,成了个字符串

其余原始类型如下

scss 复制代码
(123).toString()
'123'
('dolphin').toString()
'dolphin'
(true).toString()
'true'
(Symbol('hello')).toString()
'Symbol(hello)'
(BigInt(11)).toString()
'11'

注意:undefined和null没有这个方法,调用会报错

[] == 1 true还是false

===== 的区别就是在于前者会进行隐式类型转换,后者是严格相等

== 的比较有很多种情况:带注释的 ES5 --- Annotated ES5

这里就不带大家一一查看了,总之,这里适用的情形如下

对象那一方需要调用 ToPrimitive(x)方法,这个方法我需要单独拿来说下

ToPrimitive(x , hint)

如果hintNumber,如下步骤

  1. 如果是基本类型,不进行转换
  2. 否则,调用valueOf方法,如果得到原始值,则返回
  3. 否则,调用toString方法,如果得到原始值,则返回
  4. 否则,报错

如果hintString,如下步骤

  1. 如果是基本类型,不进行转换
  2. 否则,调用toString方法,如果得到原始值,则返回
  3. 否则,调用valueOf方法,如果得到原始值,则返回
  4. 否则,报错

== 最终都是调用ToNumber,也就是说调用hintNumberToPrimitive,因此套用这个规则,[]是引用类型,走到第三步,去调用valueOf,我们都清楚,valueOf的作用是提供包装类,将其转换成原始类型的,因此,走到第三步,调用toString[].toString就是得到一个空,这个空最终再去ToNumber,空转数字就是0,因此最终得到0 == 1,返回false

[] == ![] true还是false

这个目测看肯定以为是false,但是在v8眼里,还是需要一步一步来看,首先,取非!的优先级高于==,因此先执行!,!的执行步骤是两个,现将被执行对象转成布尔,其次才是取非,因此,任何引用类型转布尔都是true,因此!true就是false,因此是[] == false , 好了,继续看,==都是要将数据调用ToNumber的,因此这个false就是0

现在就是[].ToNumber了,因为是引用类型转数字,所以最后会调用hint为数字的ToPrimitive,因此先valueOf,后再toStringvalueOf不走,因为只对包装类起作用,所以就是走toString,得到一个空,空再去调用ToNumber,得到0,因此最终就是0 == 0,返回true

最后

关于toString,你一定得搞明白,否则js的隐式类型转换你肯定会云里雾里,要是我被问到我肯定也会有点懵逼

如果你对春招感兴趣,可以加我的个人微信:Dolphin_Fung,我和我的小伙伴们有个面试群,可以进群讨论你面试过程中遇到的问题,我们一起解决

另外有不懂之处欢迎在评论区留言,如果觉得文章对你学习有所帮助,还请"点赞+评论+收藏"一键三连,感谢支持!

相关推荐
疯狂的沙粒12 分钟前
在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?
前端·uni-app·html
小妖66616 分钟前
html 滚动条滚动过快会留下边框线
前端·html
heroboyluck30 分钟前
Svelte 核心语法详解:Vue/React 开发者如何快速上手?
前端·svelte
海的诗篇_32 分钟前
前端开发面试题总结-JavaScript篇(二)
开发语言·前端·javascript·typescript
琹箐42 分钟前
ant-design4.xx实现数字输入框; 某些输入法数字需要连续输入两次才显示
前端·javascript·anti-design-vue
程序员-小李43 分钟前
VuePress完美整合Toast消息提示
前端·javascript·vue.js
Uyker1 小时前
从零开始制作小程序简单概述
前端·微信小程序·小程序
还有几根头发呀3 小时前
UDP 与 TCP 调用接口的差异:面试高频问题解析与实战总结
网络·网络协议·tcp/ip·面试·udp
Dontla5 小时前
为什么React列表项需要key?(React key)(稳定的唯一标识key有助于React虚拟DOM优化重绘大型列表)
javascript·react.js·ecmascript
EndingCoder6 小时前
React从基础入门到高级实战:React 实战项目 - 项目三:实时聊天应用
前端·react.js·架构·前端框架