彭老湿近期月报里提到了valueOf方法,兴致来了翻了下ECMA5里关于valueOf方法的介绍,如下:

15.2.4.4 Object.prototype.valueOf ( )
When the valueOf method is called, the following steps are taken:
1. Let O be the result of calling ToObject passing the this value as the argument.
2. If O is the result of calling the Object constructor with a host object (15.2.2.1), then
a. Return either O or another value such as the host object originally passed to the constructor. The specific result that is returned is implementation-defined.
3. Return O.

规范里面的对于valueOf的解释很短,大致为:调用ToObject方法(一个抽象方法,后面会讲到),并将this的值作为参数传入。

针对调用ToObject时传入的不同参数(this),返回值分别如下:

1、this为宿主对象时,返回值取决于浏览器的实现,即不同浏览器的返回可能不同(关于宿主对象,可参考http://www.w3school.com.cn/js/pro_js_object_types.asp)

2、this不是宿主对象,则返回ToObject(this)的值

参数类型   返回结果
Undefined 抛出TypeError异常
Null 抛出TypeError异常
Number 创建一个Number对象,它内部的初始值为传入的参数值
String 创建一个String对象,它内部的初始值为传入的参数值
Boolean 创建一个Boolean对象,它内部的初始值为传入的参数值
Object 返回传入的参数(无转换)

根据Object.prototype.valueOf的定义,以及抽象方法ToObject的描述,可得下表

obj类型   Object.prototype.valueOf.call(obj)返回结果
Undefined 抛出TypeError异常
Null 抛出TypeError异常
Number Number类型的对象,值等于obj
String String类型的对象,值等于obj
Boolean Boolean类型的对象,值等于obj
Object obj对象本身

举几个具体的例子:

var num = 123;
console.log(num.valueOf());  //输出:123
console.log(num.valueOf());  //输出:'number'var unde = undefined;
console.log(Object.prototype.valueOf.call(unde));  //输出:'TypeError: Cannot convert null to object'var obj = {name:'casper'};
var linkObj = obj.valueOf();
linkObj.name = 'change';
console.log(linkObj.name);  //输出:'change' ...说明obj.valueOf()返回的是对象自身

实际上,上面没有提到Array、Function对象,根据下面代码可以猜想,当Object.prototype.valueOf调用时,参数为Array、Function类型的对象时,返回的结果也为对象自身:

var arr = [1, 2 ,3];
var linkArr = arr.valueOf();
linkArr[0] = ['casper'];
console.log(linkArr);  //输出:['casper', 2, 3]var foo = function(){ return 1; };
var linkFoo = foo.valueOf();
linkFoo.test = 'casper';
console.log(linkFoo.test);  //输出:'casper'

看完上面的描述,是不是有种恍然大悟的感觉?如果是的话,恭喜你,可能你跟我一样其实还没完全理解透彻。

简单举个例子,当调用Object.prototype.valueOf的对象为数值类型时,假设该对象是名称为num,num很有可能通过下面两种方式声明:

var num = 123;  //通过对象字面量声明console.log(typeof num);  //输出:'number'
var num = new Number(123);  //通过构造方法声明console.log(typeof num);  //输出:'object'

更多变态声明方式,可参见《一眼毁三观:JS中不为人知的五种声明Number的方式》

关于返回值的说明,ECMA5里面原文如下:

Create a new Number object whose [[PrimitiveValue]] internal property is set to the value of the argument. See 15.7 for a description of Number objects.

按照这段文字的说明,似乎num.valueOf()返回的应该是个Number对象(非字面量声明的那种),但实际上:

var num = 123;
var tmp = num.valueOf();
console.log(typeof tmp);  //输出: 'number'

这是怎么回事呢?于是又仔细翻看了下,似乎有些接近真相了:

5.7.4.4 Number.prototype.valueOf ( )

Returns this Number value.

The valueOf function is not generic; it throws a TypeError exception if its this value is not a Number or a Number object. Therefore, it cannot be transferred to other kinds of objects for use as a method.

原来Number有属于自身的原型valueOf方法,不是直接从Object.prototype上继承下来,类似的,Boolean、String也有自己的原型valueOf方法,归纳如下:

类型     是否有属于自己的原型valueOf方法
Undefined
Null
Number 有,Number.prototype.valueOf
String 有,String.prototype.valueOf
Boolean 有,Boolean.prototype.valueOf
Object -

此处之外,Array、Function并没有自己的原型valueOf方法,见规范说明:

NOTE The Array prototype object does not have a valueOf property of its own; however, it inherits the valueOf property from the standard built-in Object prototype Object.

The Function prototype object does not have a valueOf property of its own; however, it inherits the valueOf property from the Object prototype Object.

补充说明:Number.prototype.valueOf的内部转换规则比想的要略复杂些,此处不展开。

JS中的valueOf方法相关推荐

  1. JS中通过call方法实现继承

    JS中通过call方法实现继承 原文:JS中通过call方法实现继承 讲解都写在注释里面了,有不对的地方请拍砖,谢谢! <html xmlns="http://www.w3.org/1 ...

  2. JS中的Replace方法

    最近查一个bug,原因是JS中的Replace方法造成的,当将一个字符串中有处需要替换时,一般会用到JS中的Replace方法,Replace方法的第一个参数如果是传的字符串,只会替换第一处.代码如下 ...

  3. java script eval_「eval」js中的eval方法详解(一)–eval方法的初级应用 - seo实验室...

    eval 在我看来,js中的eval()方法就是一个js语言的执行器,它能把其中的参数按照javaScript语法进行解析并执行. 语法: eval(s); eval()方法中的参数s有多种情况.参数 ...

  4. JS中创建对象的方法

    JS中创建对象的方法 最近手头一个项目刚完成,下一个显目还在准备中,趁这个空档期,拿起尘封多年的JS书, 重温一遍JS面向对象程序设计,然后就得出下文,算是一个总结吧. 也许,你会说 "创建 ...

  5. jquery中的map()方法与js中的map()方法

    1.jquery中的map()方法 首先看一个简单的实例: $("p").append( $("input").map(function(){ return $ ...

  6. js中的字符串方法与数组方法总结

    js中的字符串方法与数组方法总结 1.字符串方法 2.数组方法

  7. 请尽可能说出js中数组的方法,最少3个,越多越好

    我接下来要把数组方法全都过一遍,顺手做个整理. 至于为什么整理这个,最近总听说面试经常会问到这个问题, 面试官灵魂发问:请尽可能说出js中数组的方法,最少3个,越多越好 据可靠消息了解到,如果你回答的 ...

  8. slice在php里面什么意思,js中slice()使用方法

    本文主要和大家分享js中slice()使用方法,slice()通过索引位置获取新的数组,该方法不会修改原数组,只是返回一个新的子数组. 用法:arrayObj.slice(start,end)arra ...

  9. js中的slice方法(开始索引,结束索引-不包含该索引元素)-截取和splice方法-删除(开始索引,删除个数)和插入-(开始索引,删除个数,插入内容)

    js中的slice方法(开始索引,结束索引-不包含该索引元素)-截取和splice方法-删除(开始索引,删除个数)和插入-(开始索引,删除个数,插入内容) 1.slice(start,end)-截取 ...

最新文章

  1. Tornado做鉴权服务性能实践
  2. 蓝桥杯 历届试题 九宫重排
  3. Android自定义view之圆形进度条
  4. Linux启动和退出系统的方法,实验二 Linux的启动与关闭
  5. 音频源代码_使用开放源代码从丢失的格式中恢复音频
  6. 【bzoj4327】JSOI2012 玄武密码 AC自动机
  7. python有什么优秀功能_Python都有什么强大的功能
  8. 一篇牛B的 纹理映射 大全
  9. 【Python】从0到1:30行代码制作表白窗口!(可直接copy + 运行哦~)
  10. 基于单片机的室内安全环境监测系统的设计
  11. 【交叉编译】配置交叉编译工具链
  12. C# 合并Excel工作表
  13. 矩阵平方差公式成立条件的探讨
  14. Linux alarm闹钟函数
  15. intel服务器芯片组,能玩四通道?Intel下代芯片组深入分析
  16. 日语动词+动词类型+动词活用
  17. HTML5手机页面触屏滑动上下翻页特效
  18. 直播行业的梦幻泡影:主播们的数据人生
  19. 频域串联滞后校正matlab,控制工程基础(基于Matlab的线性系统串联校正)
  20. HBuilder教程

热门文章

  1. 我的创作纪念日,成为创作者的第512天
  2. 案例 APP Store 数据分析
  3. 自动化办公之excel教程(6):数据的分析和处理
  4. HTC vive pro unity开发者软件/SDK版本注意事项
  5. 大学计算机科学的14个知识领域
  6. 虚拟机VMware的下载、安装与激活(超详细)
  7. linux的shell命令行参数,shell脚本命令行参数简介
  8. 14.Python的类和对象
  9. linux学习路线-韦东山:史上最全嵌入式Linux学习路线图
  10. 插入排序实现——直接插入排序和希尔排序