JavaScript中valueOf、toString的隐式调用

开发 前端
今天在群上有人问这样一个问题

今天在群上有人问这样一个问题:

函数add可以实现连续的加法运算
函数add语法如下
add(num1)(num2)(num3)...;//注意这里是省略号哟,***
使用举例如下:
add(10)(10)=20;
add(10)(20)(50)=80;
add(10)(20)(50)(100)=180;
请用js代码实现函数add。

自个琢磨了一会只能Google之,代码如下:

  1. function add(num){ 
  2.         var sum=num, 
  3.          
  4.             tmp=function(v){ 
  5.                 sum+=v; 
  6.                 return tmp 
  7.             }; 
  8.          
  9.         tmp.toString=function(){ 
  10.             return sum 
  11.         }; 
  12.          
  13.         return tmp 
  14.     } 
  15.      
  16.      
  17.     alert( add(10)(20)(50) )        //80 

起初没弄懂为什么会返回80,因为toString方法一直没被调用啊,怎么会返回sum呢;后来知道原来toString被隐式调用了,也就有了下文。

先引用一段话

 

每个对象的toString和valueOf方法都可以被改写,每个对象执行完毕,如果被用以操作JavaScript解析器就会自动调用对象的toString或者valueOf方法,举栗子:

 

  1. //我们先创建一个对象,并修改其toString和valueOf方法 
  2.     var obj={ 
  3.          
  4.         i:10, 
  5.          
  6.         valueOf:function(){ 
  7.              
  8.             console.log('执行了valueOf()'); 
  9.              
  10.             return this.i+20 
  11.              
  12.         }, 
  13.          
  14.         toString:function(){ 
  15.              
  16.             console.log('执行了toString()'); 
  17.              
  18.             return this.valueOf()+20 
  19.         } 
  20.     } 
  21.      
  22.     //当我们调用的时候: 
  23.      
  24.     alert( obj )    //50       执行了toString() 执行了valueOf() 
  25.     alert( +obj )    //30       执行了valueOf() 
  26.     alert( obj>40 )    //false       执行了valueOf() 
  27.     alert( obj==30 )    //true       执行了valueOf() 
  28.     alert( obj===30 )    //false 
  29.     //***这个未输出任何字符串,个人猜想是这样的:全等比较时,js解析器直接先判断类型是否一样,明显一个是Object,一个是Number,所以直接不相等,根本不需要再去求值了。 

由上可以看出,虽然我们没有调用obj的任何方法,但是要使用obj进行操作时,好像(其实就是,如果我们是创造js解析器的人这些就不是问题了,哎)js解析器自动帮我们调用了其toString或valueOf方法。

接下来就是探究什么时候执行的是toString方法,什么时候执行的是valueOf方法了。大致猜这样:如果做加减乘除、比较运算的时候执行的是valueOf方法,如果是需要具体值呢就执行的是toString方法。更严谨的实验复制一下,请原谅(原文地址):

 看到这里,我们回顾一下之前我们使用 字符串和数字加减 等操作的隐式转换:

 

  1. var age = 30; 
  2. age.toString() + 'year old'// '30 year old' 
  3. age + ' years old'// '30 years old' 

在运行 age.toString() + 'year old'时,age变量通过调用toString函数显式的从Number型转换成String型。而在运行age + ' years old'时,我们没有显式的调用函数,age也被转换成String型,这里就是javascript引擎做了隐式类型转换。隐式类型转换可以认为 javascript引擎调用的相应的类型转换函数来进行类型转换,age + ' years old'其实等价于age.toString() + 'years old',隐式类型转换和显式类型转换其实是一回事情(当然,具体怎么优秀的做隐式转换的还是造js解析器的人最清楚,他怎么不告诉我们怎么造的呢... (☆▽☆)...这样的游戏好玩么[[137874]])。
哈哈,其实就是之前没对隐式类型转换做深入研究,只知道,哦是这样,隐式类型转换嘛。所以换个上面add函数的形式就不知道是怎么回事了,不过现在算是弄清楚了(吧)。

参考:

http://www.cnblogs.com/rubylouvre/archive/2010/10/01/1839748.html

http://zjuwwq.gitbooks.io/jump_javascript/content/data_types/type_conversion.html

责任编辑:王雪燕 来源: 博客园
相关推荐

2023-12-05 08:18:51

函数valueOf

2010-01-07 17:42:23

Linux动态库

2023-08-14 08:35:36

2017-09-13 10:58:51

JavaScript转换规则

2010-11-16 15:11:52

Oracle隐式游标

2017-09-05 16:17:35

JavaScript运算转换

2023-09-22 09:04:00

C++编程

2020-09-25 15:40:22

toStringvalueOf前端

2010-06-22 13:32:26

函数式编程JavaScript

2019-07-23 15:04:54

JavaScript调用栈事件循环

2023-12-12 08:50:22

MySQL隐式转换varchar

2009-07-20 17:59:07

JavaScript调ASP.NET AJA

2009-07-21 13:54:55

Scala重载方法隐式转换

2022-02-23 21:24:21

索引SQL字符

2024-08-28 08:50:11

MySQL核心模块

2010-07-30 12:56:02

Flex调用JavaS

2017-07-28 09:39:12

隐式IntentAndroid M

2009-09-03 13:50:22

ToString(st

2009-04-21 09:37:50

ASP.NETAjaxJavaScript

2009-09-01 10:49:28

C#具有隐式类型声明
点赞
收藏

51CTO技术栈公众号