Javascript 隐式转换 和 toString + valueOf

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/palmer_kai/article/details/84555238

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>

猜你喜欢

转载自blog.csdn.net/palmer_kai/article/details/84555238
今日推荐