要了解 Object.prototype.toString.call()
,就需要先知道 Object.prototype.toString
函数的作用。
Object.prototype.toString 执行过程
规范 ECMAScript 5.1 (ECMA-262) 中对Object.prototype.toString()
的执行步骤描述如下:
When the toString method is called, the following steps are taken:
- If the this value is undefined, return "[object Undefined]".
- If the this value is null, return "[object Null]".
- Let O be the result of calling ToObject passing the this value as the argument.
- Let class be the value of the [[Class]] internal property of O.
- Return the String value that is the result of concatenating the three Strings "[object ", class, and "]".
简单翻译下。
当调用 toString
方法时,将执行以下步骤:
1、如果 this
值为 undefined
,返回 [object Undefined]
;
2、如果 this
值为 null
,返回 [object Null]
;
3、将 this
值作为 ToObject
参数,ToObject
返回值赋给为 O
;
4、设置 class
的值为 O
对象的 [[Class]]
值;
5、返回 "[object "
、class
与 "]"
的拼接结果。
注:ToObject 操作可将 Boolean、Number、String、Object 转为一个对象。
关于 [[class]] 的值,规范中有这么一段:
The value of the [[Class]] internal property is defined by this specification for every kind of built-in object. The value of the [[Class]] internal property of a host object may be any String value except one of "Arguments", "Array", "Boolean", "Date", "Error", "Function", "JSON", "Math", "Number", "Object", "RegExp", and "String". The value of a [[Class]] internal property is used internally to distinguish different kinds of objects. Note that this specification does not provide any means for a program to access that value except through Object.prototype.toString。
这里的重点是:[[class]] 的值有 "Arguments", "Array", "Boolean", "Date", "Error", "Function", "JSON", "Math", "Number", "Object", "RegExp", and "String"。
了解了 Object.prototype.toString()
函数的执行过程,现在可以来看它有什么作用了。
Object.prototype.toString 作用
Object.prototype.toString
主要根据 this
值类型来返回不同的字符串。我们可以据此来判断 value
类型。
使用 Object.prototype.toString.call 判断类型
call
可改变上下文,也就是改变 this
值。我们将需要判断类型的值作为参数传进 Object.prototype.toString.call
里。
基本上所有类型除了 Object
都继承自 Object
,所以都自带 toString
方法,但有些类型重写了 toString
函数,比如
[1, 2].toString(); // "1, 2"
调用这些被重写的 toString
会影响结果,所以我们使用 Object.prototype.toString
来判断类型。当然,Object.prototype.toString
也可以被改写,但几乎不会有人那么做(毕竟改写 Object
方法会影响到其他所有对象),是相对安全的。
判断结果如下:
Object.prototype.toString.call(123); // "[object Number]"
Object.prototype.toString.call('123'); // "[object String]"
Object.prototype.toString.call(true); // "[object Boolean]"
Object.prototype.toString.call({}); // "[object Object]"
Object.prototype.toString.call(function a() {}); // "[object Function]"
Object.prototype.toString.call(null); // "[object Null]"
Object.prototype.toString.call(undefined); // "[object Undefined]"
Object.prototype.toString.call(); // "[object Undefined]"
Object.prototype.toString.call([1, 2]); // "[object Array]"
Object.prototype.toString.call(new Date()); // "[object Date]"
我们可以据此写一个函数用于判断类型。
function getType (value) {
const str = Object.prototype.toString.call(value)
return /^\[object (.*)\]$/.exec(str)[1]
}
ECMAScript 新规范中对于 Object.prototype.toString()
的执行步骤有所改变,这里不再叙述。有兴趣可自行查阅。
网友评论