资讯专栏INFORMATION COLUMN

javascript中让人懵逼的类型转换

didikee / 976人阅读

摘要:核心点中的强制类型转换总是返回标量基本类型值。数字化对象在强制转换为数字的时候,会优先调用方法,如果返回基本类型的值,则直接使用该返回值如果返回值不是基本类型,则会继续调用方法,如果返回基本类型的值,则直接使用该返回值,否则报错。

最近在读《你不知道的javascript》系列图书,收获蛮大,感慨也挺多的。
是的,关于javascript,你不是不知道,而是真的不知道。?
就比如类型转换,从开始到看完到第二第三第N遍,我经历了如下的心路历程:
这有什么不知道的 → 一脸懵逼 → 有点意思 → 卧槽,怎么这样? → 原来是这样 → 靠,还是坑...
真可谓是不学不知道,一学吓一跳。
为了避免再次入坑,这里做个总结,不,了结。

核心点

Javascript中的强制类型转换总是返回标量基本类型值(string, boolean, number, undefined, null)。
直白点就是Object.toString()或者Object.valueOf()的返回值。

toString和valueOf的区别

toString : 以字符串形式返回该对象的原始值

valueOf : 返回最适合该对象类型的原始值

在数值运算中,会优先调用valueOf

在字符串运算中,会优先调用toString

var a = 1;
a.toString() // "1"
a.valueOf() // 1

a + 2 // 3 优先调用valueOf
a + "string" // 1string 优先调用toString

a + "" //隐式强制类型转换
String(a) //显示强制类型转换
规则 ToString 字符串化

对象在强制转换为字符串的时候,会优先调用toString()方法,如果返回基本类型的值,则直接使用该返回值;
如果返回值不是基本类型,则会继续调用valueOf()方法,如果valueOf()返回基本类型的值,则直接使用该返回值,否则报错。
数组默认的toString方法经过了重新定义,类似于数组的join(",")方法,会将数组的各个元素以","分隔返回。这就是 String([]) === "" 的原因。

JSON.stringify易错点

JSON.stringify对象中遇到undefined、function、symbol时会自动忽略

JSON.stringify数组中遇到undefined、function、symbol时会返回null

字符串、数字、布尔、null的JSON.stringify的规则与ToString相同

如果传递给JSON.stringify的对象中定义了toJSON()方法,那么该方法会在字符串化前调用。

JSON.stringify({a : undefined, b : function () {}, c: 1}) // "{"c":1}"
JSON.stringify([undefined, function () {},1])  // "[null, null, 1]"
ToNumber 数字化

对象在强制转换为数字的时候,会优先调用valueOf()方法,如果返回基本类型的值,则直接使用该返回值;
如果返回值不是基本类型,则会继续调用toString()方法,如果toString()返回基本类型的值,则直接使用该返回值,否则报错。

Number([]),因为[].valueOf()返回值不是基本类型,因此会调用toString(), 等价于Number("")

ToBoolean 布尔化
假值

javascript有以下假值:

undefined

null

false

+0、-0 和 NaN

""

假值的布尔强制类型转化为false
可以理解为假值列表以外的都是真值(true)

== 和 === 的区别

== 允许在相等比较中进行强制类型转换,=== 不允许

== 和 === 都会检查操作数的类型,区别在于操作数类型不同时他们的处理方式不同,即== 会进行强制类型转换

容易懵逼的地方
null == undefined
NaN  != NaN
null != 0
undefined != 0
NaN != 0
[] == false
[] == 0
[] == ""
[] == ![]
正确的使用 ==

如果两边的值中有true或者false,千万不要使用 ==

如果两边的值中有[]、"" 或者 0, 尽量不要使用 ==

其他

+运算符 (即只有一个操作数) 用来强制转化为数字 + new Date()

&& 和 || 运算符的返回值并不一定是布尔类型,而是两个操作数其中一个的值

参考

《你不知道的JavaScript(中)》

本文首发于 我的博客

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/82878.html

相关文章

  • javascript对象不完全探索记录02:疯狂打call!给谁打call?打什么call?

    摘要:注意该方法的作用和方法类似,只有一个区别,就是方法接受的是若干个参数的列表,而方法接受的是一个包含多个参数的数组。指定的参数列表。返回值返回值是你调用的方法的返回值,若该方法没有返回值,则返回。 温馨提示:作者的爬坑记录,对你等大神完全没有价值,别在我这浪费生命温馨提示-续:打call原本是属于我们偶像宅文化中的专业名词,指的是饭们在看live时在台下配合爱豆演出的节奏喊口号,举例:超...

    Shimmer 评论0 收藏0
  • 译文:JS事件循环机制(event loop)之宏任务、微任务

    摘要:译文事件循环机制之宏任务微任务原文标题这是一篇谷歌大神文章,写得非常精彩。为什么会出现这样打印顺序呢要理解这些你首先需要对事件循环机制处理宏任务和微任务的方式有了解。 译文:JS事件循环机制(event loop)之宏任务、微任务 原文标题:《Tasks, microtasks, queues and schedules》 这是一篇谷歌大神文章,写得非常精彩。译者想借这次翻译深入学习一...

    nemo 评论0 收藏0
  • jQuery源码分析1-jQuery对象的初始化

    摘要:那么为什么要在参数列表中增加呢这样做也有两个目的因为有些低版本的浏览器中是可以被重新赋值的,在自调用匿名函数的作用域内,确保是真的未定义。 1、命名空间 为什么要使用命名空间? 在一些语言中会看到有命名空间的概念,可在js中并没有,但是可以通过闭包来实现。在js闭包中定义的变量会被保存到一个作用域且不会污染全局变量,在程序运行完之后也不会被销毁。 我们可以看到,jQuery的做法就是使...

    qiangdada 评论0 收藏0
  • 【译】理解JavaScript:闭包

    摘要:当面试中让我解释一下闭包时我懵逼了。这个解释开始可能有点晦涩,让我们抽丝剥茧摘下闭包的真面目。此文不详述作用域有专门的主题阐述,不过作用域是理解闭包原理的基础。这才是闭包的真正便利之处。闭包使用不当就会很坑。 原文链接 为什么深度学习JavaScript? JavaScript如今是最流行的编程语言之一。它运行在浏览器、服务器、移动设备、桌面应用,也可能包括冰箱。无需我举其他再多不相干...

    岳光 评论0 收藏0
  • 深入js隐式类型转换

    摘要:结合实际中的情况来看,有意或无意中涉及到隐式类型转换的情况还是很多的。此外当进行某些操作时,变量可以进行类型转换,我们主动进行的就是显式类型转换,另一种就是隐式类型转换了。 前言 相信刚开始了解js的时候,都会遇到 2 ==2,但 1+2 == 1+2为false的情况。这时候应该会是一脸懵逼的状态,不得不感慨js弱类型的灵活让人发指,隐式类型转换就是这么猝不及防。结合实际中的情况来看...

    tomato 评论0 收藏0

发表评论

0条评论

didikee

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<