js弱类型转换的知识点

本文属于转载知识点,以下是原博文作者:不死鸟哇的文章,文章链接:原文JavaScript里什么情况下a==!a为true呢?

今天群里有位同学问了这样一个问题,JavaScript在什么情况下会出现变量a == !a为true呢?据说是在司徒正美的书里看到的。我觉得这个问题有点意思,涉及到了隐式类型转换的问题,与大家分享一下吧!

    答案是当a = []的时候,这个答案我一开始也没想出来。而是在调试器试了几次之后知道的。但是其中的原因我是明白的。这是因为JavaScript的类型转换。

    我们先来考虑这个问题,console.log([] == false)会打印什么呢?

    答案是true。为什么呢?

    首先,因为当"=="号两边其中一个是布尔值的话,先把它转换为数字(ECMAScript的规范)。于是就变成了求[] == 0。

    然后问题是为什么[]==0会是true呢?这是因为当"=="的一边是字符串或数字,另一边是对象的时候(数组也是对象),先把对象值转换为原始值再判断相等。对象值到原始值是怎么转换的呢?.对于所有非日期雷对象来说,对象到原始值的转换基本上就是对象到数字的转换。有3个步骤:

    1.所有对象先调用valueOf()方法,如果此方法返回的是原始值,则对象转为这个原始值。

    2.如果valueOf方法返回的不是原始值,则调用toString方法,如果toString方法返回的是原始值吗,则对象转换为这个原始值。

    3.如果valueOf和toString方法均没有返回原始值,则抛出TypeError异常.

好,让我们看看[]到原始值的转换是怎么样的?首先调用[].valueOf()方法,返回值是对象自身,即[],这不是一个原始值。所以继续调用[].toString()方法,返回的是空字符串"",这是一个原始值,所以此值就作为对象转换为原始值的输出。于是问题就变成了求"" == 0.

    最后,为什么"" == 0会是true呢?相信很多同学都知道了,当"=="两边一个是字符串一个是数字的时候,先把字符串转为数字,再进行比较。“”转成数字为0,所以最后得出[] == false为true。

    让我们回到标题 [] == ![]为什么是true。!的优先级比==要高,所以会先执行![]。也就是先把[]转为布尔类型再取反。[]转布尔值是true,为什么呢?因为在JavaScript里除了false自身以外只有5个假值,分别是“”,undefined, null, 0, NaN。除了这5个假值以外,其他所有值转布尔类型都是true。一切对象都是真值,包括new Boolean(false)。于是问题就成了刚才我们讨论的 [] == false了。故得到 [] == ![]为true。

posted @ 2017-07-31 22:05  fantasy-zxf  阅读(935)  评论(0编辑  收藏  举报