Javascript 隐式转换 和 toString + valueOf

Aphorism

Grow in errors

一、 js 数据类型

原始值类型 primitive type(基本/简单): String, Number, Boolean, undefined, null

引用类型: Array, Function, Object

补充: 基本包装类型:String, Number, Boolean,

二、Object.prototype.valueOf

The valueOf() method returns the primitive value of the specified object.

JavaScript calls the valueOf method to convert an object to a primitive value. You rarely need to invoke the valueOf method yourself; JavaScript automatically invokes it when encountering an object where a primitive value is expected.

By default, the valueOf method is inherited by every object descended from Object.

Every built-in core object overrides this method to return an appropriate value. If an object has no primitive value, valueOf returns the object itself.

每个内置对象已经复写过了 valueOf 方法, 这个和 隐式转换有关

You can use valueOf within your own code to convert a built-in object into a primitive value. When you create a custom object, you can override Object.prototype.valueOf() to call a custom method instead of the default Object method.

三、Object.prototype.toString

The toString() method returns a string representing the object

Every object has a toString() method that is automatically called when the object is to be represented as a text value or when an object is referred to in a manner in which a string is expected. By default, the toString() method is inherited by every object descended from Object.

If this method is not overridden in a custom object, toString() returns “[object type]”, where type is the object type.

四、上述主要信息

  1. js 中的对象(一切) 都具备 toString 和 valueOf 方法
  2. 内置对象(除了 Object) 其中包含了 基本包装类型 的 toString 和 valueOf 方法 已经被复写了

五、传送门

可以看看这篇文章:https://blog.csdn.net/u010552788/article/details/51073767?utm_source=blogxgwz3

参阅文章信息重点:

一般情况下,在隐式转换的时候, 首先访问的是 对象的valueOf 方法,若返回值是 原始值类型,则转换为该值; 否则, 会调用对象的 toString 方法,若返回值是 原始值类型,则转换为该值,否则报错

转换前的值 (对象) --> valueOf()[ --> toString() ] --> 转换后的值(原始值

通过 valueOf 或者 toString 将对象隐式转换成 原始值, 一般先调用 valueOf ,若两个方法都不能得到原始值,则报错

(index):13 Uncaught TypeError: Cannot convert object to primitive value
    at Date.[Symbol.toPrimitive] (<anonymous>)
    at (index):13

六、特例: Date 对象实例

// Date.prototype.toString = null;
var date = new Date();
console.log('1' + date); //1Mon Nov 26 2018 22:40:59 GMT+0800 (China Standard Time)
console.log(1 + date); //(index):13 1Mon Nov 26 2018 22:40:59 GMT+0800 (China Standard Time)
console.log(1 * date); //(index):14 1543243259716

经测试, toString 不存在的时候, 也会 调用 vlaueOf

八、 拓展

数据类型判断
typeOf

用 typeOf 可以判断 原始值类型和 函数 但是 其他内置对象就很难区分了

var str = 'hello,world',
				num = 123,
				bool = true,
				arr = [],
				obj = {},
				fn = function () {},
				date = new Date(),
				Rex = new RegExp();
				math = Math;

		console.log(typeof str); // string
		console.log(typeof num); // dataType.html:19 number
		console.log(typeof bool); // dataType.html:20 boolean
		console.log(typeof arr); // dataType.html:21 object
		console.log(typeof obj); // dataType.html:22 object
		console.log(typeof fn); // dataType.html:23 function
		console.log(typeof date); // dataType.html:24 object
		console.log(typeof Rex);// dataType.html:25 object 
		console.log(typeof math);// dataType.html:26 object 
Object.prototype.toString.call()…

所以我们可以 通过 toString 这个 展现(代表)已知对象的 方法来判断 数据类型,由于内置对象 的toString 方法都被复写了,所以我们 可以 调用 Object 的 toString 方法, 返回的就是[object type]

console.log(Object.prototype.toString.call(str)); // [object String]
	console.log(Object.prototype.toString.call(num)); // dataType.html:35 [object Number]
	console.log(Object.prototype.toString.call(bool)); // dataType.html:36 [object Boolean]
	console.log(Object.prototype.toString.call(arr)); // dataType.html:37 [object Array]
	console.log(Object.prototype.toString.call(obj)); // dataType.html:38 [object Object]
	console.log(Object.prototype.toString.call(fn)); // dataType.html:39 [object Function]
	console.log(Object.prototype.toString.call(date)); // dataType.html:40 [object Date]
	console.log(Object.prototype.toString.call(Rex)); // dataType.html:41 [object RegExp]
	console.log(Object.prototype.toString.call(math)); // dataType.html:42 [object Math]

九、没必要看的内容

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>valueOf 和 toString 的先后</title>
</head>
<body>
	<script>
		Date.prototype.toString = null;

		var date = new Date();
		console.log('1' + date);

		console.log(1 + date);
		console.log(1 * date);

	/*	var person = {
			toString: function () {
				console.log('toString');
			},
			valueOf: function () {
				console.log('valueOf');
			}
		}

		console.log(1 + person); // Object valueOf 为本身, 先valueOf
		console.log('1' + person);
		console.log( 1*person);*/

	/*	Array.prototype.toString = function () {
			console.log('toString');
		}

		Array.prototype.valueOf = function () {
			console.log('valueOf');
			return this;
		}


		var arr = [1,2,3]; // Array valueOf 为本身先 valueOf
		console.log(1 + arr);
		console.log('1' + arr);
		console.log(1 * arr);
*/
/*		Function.prototype.toString = function () {
			console.log('toString');
		};

		Function.prototype.valueOf = function () {
			console.log('valueOf');
			return this;
		}

		var fn = new Function(); // Function valueOf 为 本身 先 valueOf

		console.log(1 + fn);
		console.log('1' + fn);
		console.log(1*fn);
*/
	/*String.prototype.toString = function () {
		console.log('toString');
	};

	String.prototype.valueOf = function () {
		console.log('valueOf');
	};

	var str = new String('hello,world'); //String valueOf 本身, 先valueOf

	console.log(1 + str);
	console.log('1' + str);
	console.log(1 * str); */
/*	Number.prototype.valueOf = function () { // Number valueOf 先 valueOf
		console.log('toString');
	};

	Number.prototype.valueOf = function () {
		console.log('valueOf');
	};
	var num = new Number(1);

	console.log(1 + num);
	console.log('1' + num);
	console.log(1 * num);*/

/*	Boolean.prototype.valueOf = function () {  // Boolean valueOf 先 valueOf
		console.log('toString'); 
	};

	Boolean.prototype.valueOf = function () {
		console.log('valueOf');
	};
	var bool = new Boolean(true);

	console.log(1 + bool);
	console.log('1' + bool);
	console.log(1 * bool);*/
	</script>
</body>
</html>
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值