我知道我们可以在Javascript中检测变量的类型:
Object.prototype.toString.call([]); // [object Array]
Object.prototype.toString.call({}); // [object Object]
Object.prototype.toString.call(''); // [object String]
Object.prototype.toString.call(new Date()); // [object Date]
Object.prototype.toString.call(1); // [object Number]
Object.prototype.toString.call(function () {}); // [object Function]
Object.prototype.toString.call(/test/i); // [object RegExp]
Object.prototype.toString.call(true); // [object Boolean]
Object.prototype.toString.call(null); // [object Null]
Object.prototype.toString.call(); // [object Undefined]
但为什么呢?
这些值([object Array],[object String] ...)是如何返回的,以及Object.prototype.toString
的作用是什么?
答案 0 :(得分:6)
Object.prototype.toString
基本上返回对象的[[Class]]
(实现细节)内部属性。从ECMA Script 5.1规范中引用the section,其中定义了
- 如果
this
值为undefined
,请返回"[object Undefined]"
。- 如果
this
值为null
,请返回"[object Null]"
。- 让 O 成为调用
ToObject
传递this
值作为参数的结果。- 让 class 为 O 的
[[Class]]
内部属性的值。- 返回串联三个字符串
醇>"[object "
,class
和"]"
的结果的字符串值。
此外,
[[Class]]
内部属性的值由此规范为每种内置对象定义。宿主对象的[[Class]]
内部属性的值可以是除"Arguments"
,"Array"
,"Boolean"
,"Date"
,{{1}之外的任何字符串值},"Error"
,"Function"
,"JSON"
,"Math"
,"Number"
,"Object"
和"RegExp"
。内部使用"String"
内部属性的值来区分不同类型的对象。 请注意,除了[[Class]]
之外,此规范不提供程序访问该值的任何方法。
因此,Object.prototype.toString
是唯一可以访问Object.prototype.toString
属性的函数。
答案 1 :(得分:0)
如果您正在使用ECMA 6(如在NodeJS或更新的浏览器技术上),您可以使用以下函数来获取“类名”。
// primitives
var array = [], obj = {}, str = "", date = new Date(),
num = 1, flt = 1.0, reg = new RegExp(/woohoo/g),
bool = true, myType = new MyType(), udf = undefined, nul = null;
// names of various types (primitive and not)
var names = cName(array) + ", " + cName(obj) + ", " + cName(str) + ", " +
cName(num) + ", " + cName(flt) + ", " + cName(reg) + ", " +
cName(bool) + ", " + cName(date) + ", " + cName(myType) + ", " +
cName(MyType) + ", " + cName(udf) + ", " + cName(nul);
// custom type
function MyType(){}
console.log( names );
// output:
// Array, Object, String, Number, Number, RegExp, Boolean, Date, MyType, MyType, undefined, null
// implementation
function cName(obj){
// default to non-null value.
var ret = '';
if(typeof obj === 'undefined') { ret = 'undefined'; }
else if(obj === null) { ret = String(obj); }
else if(typeof obj.constructor !== 'undefined' && obj.constructor !== null){
ret = obj.constructor.name
if(ret == 'Function') { ret = obj.name; }
}
return ret;
}
虽然确实没有“课程”,但这有助于传递类似Array, vs Object, vs. Null
的内容,并且您想知道它是哪一个。
在其中任何一个上调用typeof
都会返回'object'
。然后有必须处理null
和undefined
之类的事情的警告。
调用Object.prototype.toString()
比访问constructor.name
更重要,因为没有从某种类型转换为字符串,我相信constructor
和constructor.name
都是成员变量,不是getter
,这意味着在检索所述名称时不会调用其他函数。