Js中toString( ) 与 valueOf( )方法、隐式转换

更新日期: 2019-06-11阅读: 2.8k标签: 对象

说明

所有的对象都继承有toString() 和 valueOf() 方法,对象到字符串,对象到数字的转换,会通过调用待转换对象的这两个方法中的一个来完成。


解释

toString( )方法的作用是:

返回一个反映这个对象的字符串,而很多类都定义了不同版本的toString( )。


({}.toString());       //=>  "[object Object]"   
[1,2].toString();      //=>  "1,2"   
true.toString();       //=>  "true"    
new Date(1970,0,1).toString();  //=>  "Thu Jan 01 1970 00:00:00 GMT+0800 (CST)"    

Error("一个错误信息").toString();    //=>  "Error: 一个错误信息"    

(function (x){return x}).toString();   //=>  "function (x){return x}"     

/\d/.toString();    //=>  "/\\d/"  或者 "/\d/" 浏览器不同返回也可能会不同


valueOf() 方法,它的作用是:

如果对象存在任意原始值,它就默认将对象转换为表示它的原始值,如果对象是复合值,而且大多数对象无法真正表示为一个原始值,因此默认的valueOf( )方法简单地返回对象本身,而不是返回一个原始值。

数组、函数、和正则表达式简单的继承了这个默认方法,调用这些类型的实例的valueOf( )方法只是简答返回对象本身。

日期类定义的valueOf( )方法会返回它的一个内部表示:1970年1月1日以来的毫秒数。

[1,2].valueOf();  //=>  [1,2]  

(function (){}).valueOf();   //=>  function (){}

/\d/.valueOf();    //=>  /\d/  

new Date().valueOf();   //=>  1502941383029

原始值:不可变更的值,包括undefined、null、布尔值、数字、和字符串。 
看下面这张图,列出了一些基本的类型转换,这张图来自 JavaScript权威指南。


好了,我们现在已经了解toString( )方法 和 valueOf( )方法了,下来我们来说说,对象到字符串和对象到数字的转换。


对象到字符串的转换:

1、如果对象具有toString( )方法,则调用这个方法。如果她返回一个原始值,JavaScript将这个值转换为字符串(如果本身不是字符串的话),并返回这个字符串结果。 
2、如果对象没有toString( )方法,或者这个方法并不返回一个原始值,那么JavaScript会调用valueOf( )方法。如果存在这个方法,则JavaScript调用它。如果返回值是原始值,JavaScript将这个值转换为字符串(如果本身不是字符串的话),并返回这个字符串结果。
3、否则,JavaScript无法从toString()或者valueOf( )获得一个原始值,因此这时它将抛出一个类型错误异常。



对象到数字的转换:

1、如果对象具有valueOf( )方法,后者返回一个原始值,则JavaScript将这个原始值转换为数字(如果需要的话)并返回这个数字。 
2、否则,如果对象具有toString( )方法,后者返回一个原始值,则JavaScript将其转化并返回。 
3、否则,JavaScript抛出一个类型错误异常。


所以这就解释了,为什么空数组会被转换为数字0,为什么具有单个元素的数组同样会转换成一个数字。 
数组继承了默认的valueOf( )方法,这个方法返回一个对象而不是一个原始值,因此,数组到数字的转换则调用toString( )方法。空数组转换为空字符串,空字符串转换为数字0。 
含有一个元素的数组转换为字符串的结果和这个元素转换字符串的结果一样。
如果数组只包含一个数字元素,这个数字转换为字符串,在转换回数字。

JavaScript中的"+"运算符可以进行数学加法和字符串连接操作。如果它的其中一个操作数是对象,则JavaScript将使用特殊的方法将对象转换为原始值,而不是使用其他算术运算符的方法执行对象到数字的转换,"= ="相等运算符与此类似(运算隐式转换规则)。如果将对象和一个原始值比较,则转换将会遵照对象到原始值的转换方式进行。

"+" 和 "= ="应用的对象到原始值的转换包含日期对象的一种特殊情形。日期类是JavaScript语言核心中唯一的预先定义类型,它定义了有意义的向字符串和数字类型的转换。
对于所有非日期的对象来说,对象到原始值的转换基本上是对象到数字的转换(首先调用valueOf( )),日期对象则使用对象到字符串的转换模式,然而,这里的转换和上文讲述的并不完全一致:通过valueOf( )或者toString( )返回的原始值将被直接使用,而不会被强制转换为数字或字符串。

和"= ="一样,"<"运算符以及其他关系运算符也会做对象到原始值的转换,但要除去日期对象的特殊情形:任何对象都会首先尝试调用valueOf( ),然后调用toString( )。不管得到的原始值是否直接使用,它都不会进一步被转换为数字或字符串。


总结

本文说了说 toString( )方法 和 valueOf( )方法的基础知识,文中的许多概念是出自JavaScript权威指南一书,大家可以多看看书。 


扩展

可以试想下面这个运算结果,用到了上面说的相关规则进行隐式转换

(![]+[])[+!![]- -+!![]- -+!![]]+({}+[])[+!![]]+(![]+[])[+!![]- -+!![]- -+!![]]

链接: https://www.fly63.com/article/detial/3648

JavaScript中创建对象的7种模式

ECMA-262把对象定义为:”无需属性的集合,其属性可以包含基本值、对象或者函数。对象的每个属性或方法都有一个名字,而每个名字都映射到一个值。正因为这样,我们可以把ECMAScript的对象想象成散列表:无非就是一组名对值,其中值可以是数据或函数。

JavaScript数组、对象合并的多种方法实现

这篇文章讲解Js数组和对象的一些使用技巧,如何将不同的数组,对象合并/结合为1个的方法

Js通过.或者[]访问对象属性的语法、性能等区别

在JavaScript中可以使用 . 或者 [ ] 来访问对象的属性,但是对象中方法只能通过 . 来获取;使用.运算符来存取对象的属性的值。或者使用[]作为一个关联数组来存取对象的属性。但是这两种方式有什么区别了?

js中关于for...in遍历对象属性的顺序问题

对象使用obj.length时,它得到的值是undefined的,所以只能通过for...in循环获取对象的属性,我们发现并没有按属性的顺序显示,而且顺序在各个浏览器下显示也不同。 这是为什么呢?

JS声明对象时属性名加引号与不加引号的问题

JS声明对象时属性名加引号与不加引号的问题,一般情况下属性名加引号和不加引号是都可以的,效果是一样的。如果属性名是数字,则必须用“”包围,并且用 [] 方括号访问。

javascript的本地对象,内置对象和宿主对象

javascript的原生对象:也叫内部对象、本地对象、native object;内置对象:Global(全局对象)、Math ;宿主对象:有宿主提供的对象,在浏览器中window对象以及其下边所有的子对象(如bom、dom等等),在node中是globla及其子对象,也包含自定义的类对象。

JavaScript 判断对象中是否有某属性

判断对象中是否有某属性的常见方式总结,不同的场景要使用不同的方式。一点( . )或者方括号( [ ] )、二in 运算符、三hasOwnProperty()。三种方式各有优缺点,不同的场景使用不同的方式,有时还需要结合使用

JavaScript Error对象详解

error,指程序中的非正常运行状态,在其他编程语言中称为“异常”或“错误”。解释器会为每个错误情形创建并抛出一个Error对象,其中包含错误的描述信息。

如何禁止JavaScript对象重写?

由于JavaScript的灵活性,我们可以轻易地重写(override)一些于其他人定义的对象(object)。换句话说,任何人都可以重写我们所定义的对象。这是一个非常强大的特性,许多开发者都有兴趣试试,来拓展或者修改某些对象的行为。

JavaScript面向对象编程中_优雅的类写法

虽然现在已经是ES6的时代,但是,还是有必要了解下ES5是怎么写一个类的。本文详述JavaScript面向对象编程中的类写法,并分步骤讲述如何写出优雅的类。

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!