// toString()用来返回对象的字符串表示
var obj = {};
console.log(obj.toString());//[object Object]
var arr2 = [];
console.log(arr2.toString());//""空字符串
var date = new Date();
console.log(date.toString());//Sun Feb 28 2016 13:40:36 GMT+0800 (中国标准时间)
// valueOf方法返回对象的原始值,可能是字符串、数值或bool值等,看具体的对象
var obj = {
name: "obj"
};
console.log(obj.valueOf());//Object {name: "obj"}
var arr1 = [1];
console.log(arr1.valueOf());//[1]
var date = new Date();
console.log(date.valueOf());//1456638436303
前言
相信很多戳进来的人都会很好奇,CV到底是个啥东东?很厚脸皮的说那就是:ctrl+c和ctrl+v重度使用者:joy:。简单说一下copy的原因:有一篇我看了好几遍都感到头疼却重要的文章,后来一不小心去看了他的参考文章,也是该篇的原文,才豁然开朗。为了避免这种好文有一天可能莫名其妙的消失不见,因此心中就起了“歹意”,废了点时间将其抄下来。
正文
大家知道,==是JavaScript中比较复杂的一个运算符。它的运算规则奇怪,容易让人犯错,从而成为JavaScript中“最糟糕的特性”之一。
在仔细阅读了ECMAScript规范的基础上,我画了一张图,我想通过它你会彻底地搞清楚关于==的一切。同时,我也试图通过此文向大家证明==并不是那么糟糕的东西,它很容易掌握,甚至看起来很合理。先上图1
==运算规则的精确描述在此:The Abstract Equality Comparison Algorithm。但是,这么复杂的描述,你确定看完后脑子不晕?确定立马就能拿它指导实践?
肯定不行,规范毕竟是给JavaScript运行环境的开发人员看的(比如V8引擎的开发人员们),而不是给语言的使用者看的。而上图正是将规范中复杂的描述翻译成了更容易看懂的形式。在详细介绍图1中的每个部分前,我们来复习一下JS中关于类型的知识:
现在考虑表达式:
其中x和y是上述六种类型中某一种类型的值。当x和y的类型相同时,x == y可以转化为x === y,而后者是很简单的(唯一需要注意的可能是NaN),所以下面我们只考虑x和y的类型不同的情况。
一、有和无
在图1中,JavaScript值的六种类型用蓝底色的矩形表示。它们首先被分成了两组:
分组的依据是什么?我们来看一下,右侧的Undefined和Null是用来表示不确定、无或者空的,而右侧的四种类型都是确定的、有和非空。我们可以这样说:左侧是一个存在的世界,右侧是一个空的世界。
所以,左右两个世界中的任意值做==比较的结果都是false是很合理的。(见图1中连接两个矩形的水平线上标的false)
二、空和空
JavaScript中的undefined和null是另一个经常让我们崩溃的地方。通常它被认为是一个设计缺陷,这一点我们不去深究。不过我曾听说,JavaScript的作者最初是这样想的:
不管这个传闻是否可信,它们两者做==比较的结果是true是很合理的。(见图1中右侧垂直线上标的true)。在进行下一步之前,我们先来说一下图1中的两个符号:大写字母N和P。这两个符号并不是PN结中正和负的意思。而是:
注意:此处有个例外,即Date类型的对象,它会先调用toString()方法,后调用valueOf()方法。
true -> 1 false -> 0
x == y -> Number(x) == y
Number('123') // 结果123 Number('1.2e3') // 结果1200 Number('123abc') // 结果NaN Number('\r\n\t123\v\f') // 结果123
Number('') // 结果0 Number('\r\n\t \v\f') // 结果0
toString()方法用来得到对象的一段文字描述;而valueOf()方法用来得到对象的特征值。
[' '] == false
[''] == 0
' ' == 0
0 == 0
看了上面的题目,不知道你们有何感想?是不是觉得自己之前的内容没有看懂- -,下面通过分析上面的习题,来更加充分理解之前的内容。
题目1: []==[]为false
题目2: []==![]为true
题目3: {}==!{}为false
关于valueOf()方法和toString()方法的调用顺序和作用再说几句,下面来看两者的执行顺序这块
下面再来看看两者的作用
题目4: {}==![]为false
题目5: ![]=={}为fasle 题目6: []==!{}为true
题5和题6相信大家根据前面几道题的分析都能够正确的将它解答出来,因此就不细说了。看到这里,相信你们都搞明白这些让人迷糊的自动类型转换方式了吧。