toString和valueOf

零、隐式转换

Point to: 有趣的JS隐式转换

一、认识toString()

MDN:toString() 方法返回一个表示该对象的字符串。
Point to MDN: toString()

1.每个对象都有一个 toString() 方法,当对象被表示为文本值时或者当以期望字符串的方式引用对象时,该方法被自动调用。对对象x,toString() 返回 “[object type]”,其中type是对象类型。如果x不是对象,toString() 返回x应有的文本值(不是单纯的加”“)

var x = {};
console.log(x.toString());
// [object Object]

//特别的用法
toString.call(new Date); // [object Date]
toString.call(new String); // [object String]
toString.call(Math); // [object Math]

//Since JavaScript 1.8.5
toString.call(undefined); // [object Undefined]
toString.call(null); // [object Null]

//其他类型的toString():
var x = [1,2,3];
x.toString(); //返回’1,2,3’

var x = function(){console.log(‘lalala’)}
x.toString();// 返回’function(){console.log(‘lalala’)}’

var x = 12345;
x.toString();// 返回’12345’

2.可以自己定义一个对象的toString()方法来覆盖它原来的方法。这个方法不能含有参数,方法里必须return一个值。

var a = {};
console.log(a.toString());//输出[object Object]

a.toString = function() {return “a new toString”};

console.log(a + " hello" );//输出a new toString hello

console.log(a + 1);//输出a new toString1

二、认识valueOf()

MDN:valueOf() 方法返回指定对象的原始值
Point to MDN: valueOf()
1.JavaScript 调用 valueOf() 方法用来把对象转换成原始类型的值(数值、字符串和布尔值)
默认情况下, valueOf() 会被每个对象Object继承。每一个内置对象都会覆盖这个方法为了返回一个合理的值,如果对象没有原始值,valueOf() 就会返回对象自身

//一下例子均没有原始值,返回这个对象本身
var x = {};
x.valueOf(); // 返回 Object {}

var x = [1,2,3];
x.valueOf(); //返回[1, 2, 3]

var x = function(){console.log(‘lalala’)}
x.valueOf();// 返回 function (){console.log(‘lalala’)}

var x = 12345;
x.valueOf();// 返回 12345

2.可以自己定义一个对象的valueOf()方法来覆盖它原来的方法。这个方法不能含有参数,方法里必须return一个值。

var x = {};
x.valueOf = function(){
return 10;
}
console.log(x+1);// 输出10
console.log(x+“hello”);//输出10hello

三、toString() vs valueOf()

1.如果一个对象它的toString() 和 valueOf()方法均存在时,到需要调用的时候,引用哪一个方法?
看下面的问题:

//这个对象是一个函数
function fn() {
return 20;
}
console.log(fn + 10);
console.log(fn + ‘hello’);

fn.toString = function() {
return 10;
}
console.log(fn + 10);
console.log(fn + ‘hello’);

fn.valueOf = function() {
return 5;
}

console.log(fn + 10);
console.log(fn + ‘hello’);
// 输出结果分别是多少?

输出结果如下:

function fn() {
return 20;
}10
function fn() {
return 20;
}hello

20
10hello

15
5hello

从上面的结果我们可以看出:当函数fn用+连接一个字符串或者是数字的时候,如果我们没有重新定义valueOf和toString,其隐式转换会调用默认的toString()方法,将函数本身内容作为字符串返回;
如果我们自己重新定义toString/valueOf方法,那么其转换会按照我们的定义来,其中valueOf比toString优先级更高

2.再看下一个问题:如果这个对象不是函数呢?
经测试,如果这个对象是object/数组/,结果和上面的一样 ;
但如果这个对象是Date,则都调用toString();

var x = new Date(0);
//“Thu Jan 01 1970 08:00:00 GMT+0800 (马来西亚半岛标准时间)”
x.toString();
//“Thu Jan 01 1970 08:00:00 GMT+0800 (马来西亚半岛标准时间)”
x.valueOf();
//0
x+1;
//“Thu Jan 01 1970 08:00:00 GMT+0800 (马来西亚半岛标准时间)”

3.第三个问题,上面讨论了这个对象本身的类型的影响,下面讨论一些特殊情况

var x = {
toString: function () { return “foo”; },
valueOf: function () { return 42; }
};

alert(x); // foo
“x=” + x; // “x=42”
x + “=x”; // “42=x”
x + “1”; // 421
x + 1; // 43
[“x=”, x].join(""); // “x=foo”

可以看到+时,和上面的结论一样,但是alert , [x].join(“”)等这类特殊的表达,均调用toString(),当作特例记住就行了

作者:X_Jagger
来源:CSDN
原文:https://blog.csdn.net/x_jagger/article/details/73430959

你可能感兴趣的:(javascript)