JavaScript权威指南(第6版) --- 自学笔记(14) --- 对象转换为原始值

(1)对象转布尔值很简单,所有对象(包括数组和函数)都会转换为true。包括包装对象。

var a = {};
var b = [];
var c = new Boolean(false); // 包装对象,它已经不是一个原始值,而是一个对象。
var d = function() {}
console.log(Boolean(a)); // true
console.log(Boolean(b)); // true
console.log(Boolean(c)); // true
console.log(Boolean(d)); // true

(2)所有对象都继承了2个转换方法,第一个是toString(),第二个是valueOf()。
toString(),它的作用返回一个反映这个对象的字符串。

console.log({ x:1, y:2 }.toString()); // [object Object]

很多类定义了特定版本的toString()方法,例如:
数组类的toString()方法将每个数组元素转换为一个字符串,并在元素之间添加逗号,合并成结果字符串。
函数类的toString()方法返回这个函数的实现定义的表示方式,实际上,通常是将用户定义的函数,转换为js源代码的字符串。
日期类的toString()方法返回一个可读的日期时间字符串。
RegExp类的toString()方法将RegExp对象转换为表示正则表达式直接量的字符串。

console.log({ x:1, y:2 }.toString()); // [object Object]
console.log([1,2,3].toString()); // 1,2,3
var func = function(a, b) { return a + b; }
console.log(func.toString()); // function(a, b) { return a + b; }
console.log(new Date().toString()); // Mon May 20 2019 17:27:59 GMT+0800 (中国标准时间)
console.log(/\d+/g.toString()); // /\d+/g

valueOf():这个方法没有详细定义,如果存在任意原始值,它就将对象转换为表示它的原始值。对象是符合值,而且大多数对象无法真正表示一个原始值,因此默认的valueOf()方法简单地返回对象本身,而不是返回一个原始值。
日期类的valueOf()返回一个内部表示,就是从1970年1月1日到现在的毫秒数。

console.log(new Date().valueOf()); // 1558345694243

通过toString() 和 valueOf(),就可以做到对象到字符串和对象到数字的转换,但某些特殊场合,js执行了完全不同的对象到原始值的转换。

js中对象到字符串的转换经历了如下步骤:
1.)如果对象具有toString()方法,则调用这个方法。如果它返回一个原始值,js将这个值转换为字符串,并返回这个字符串结果
2.)如果对象没有toString()方法,或者这个方法不返回一个原始值,则会尝试调用valueOf(),如果存在valueOf(),则调用该方法。如果返回时原始值,js将这个值转换为字符串,并返回这个字符串结果。
3.)当js无法从toString()或者valueOf()获得一个原始值时,它将抛出一个类型错误异常。
js中对象到数字转换过程也做了上面同样的事情,只不过他会首先调用valueOf()。

根据上面过程,我们可以解释为什么空数组转换为数字时可以转换成0,具有单个数字元素的数组转换为数字时,得到一个数值。
数组继承了valueOf()方法,但是返回了一个对象,而不是原始值,因此会执行toString()方法,空数组会转换成空字符串,空字符串会转换成数字0;同理,包含一个数字元素的数组一样。

js中的"+"运算符可以进行数学加法和字符串拼接操作,如果它一个操作数是对象时,则js会使用特殊的方法将其转换为原始值,而不是使用其他算术运算符时执行对象到数字的转换。

var a = [5];
console.log(a + 1); // 51,转换到字符串,并没有转换到数字
console.log(a - 1); // 4,转换为数字
console.log(a * 2); // 10,转换为数字
console.log(a / 2); // 2.5,转换为数字

"=="运算符也类似,一个对象和一个原始值比较时,先将对象转换为原始值。

注意:日期类是js语言核心中唯一的预先定义类型,它定义了有意义的像向字符串或者数字类型的转换,对于非日期对象来说,对象到原始值得转换,基本上是对象到数字的转换(首先执行valueOf()),日期对象则使用对象到字符串转换模式。

"+"、"=="、"!="和关系运算符是唯一执行这种特殊的字符串到原始值的转换方式运算法,其他运算符到特定类型的转换都很明确,对日期对象来说也没特殊情况,例如:"-"运算符会把两个操作数都转为数字。

var now = new Date();
console.log(typeof(now + 1)); // string 隐式的将日期转为字符串
console.log(typeof(now - 1)); // number 隐式的将日期转为数字
console.log(now == now.toString()); // true 隐式和显示的将日期转为字符串
console.log(now > now - 1); // true 隐式的将日期转为数字

重要点:
(1)除日期类型以外的对象转原始值时,都是按照对象转数字的转换模式进行转换,即优先调用valueOf(),然后调用toString()
(2)日期对象则采用对象到字符串的转换模式进行转换,即优先调用toString(),然后调用valueOf()。
以上返回的原始值将被直接使用,而不会被强制转为为数字或者字符串。
(3)当然,你也可以直接调用toString()和valueOf()方法。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值