Javascript 为什么Object.prototype.toString.call(foo)可以检测到foo';s型?
我知道我们可以在Javascript中检测变量的类型,如下所示:Javascript 为什么Object.prototype.toString.call(foo)可以检测到foo';s型?,javascript,Javascript,我知道我们可以在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()); // [objec
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
做什么?基本上返回对象的[[Class]]
(实现细节)内部属性。引用ECMA脚本5.1规范,其中定义了
此
值为未定义
,则返回“[对象未定义]”
此
值为空
,则返回“[对象空]”
ToObject
并将此值作为参数传递的结果
[[class]]
内部属性的值“[对象”
,类
,和“]”
[[Class]]
内部属性的值由本规范为每种内置对象定义。主机对象的[[Class]]
内部属性的值可以是除“参数”
、“数组”
、“布尔值”
、“日期”
、“错误”
、“函数”
、“JSON”
、“数学”
、“数字”
、“对象”
“RegExp”和“String”
。[[Class]]]
内部属性的值在内部用于区分不同类型的对象。请注意,此规范不提供程序访问该值的任何方法,除非通过对象.prototype.toString
因此,
Object.prototype.toString
是唯一可以访问[[Class]]]
属性的函数。如果您碰巧使用的是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
和未定义的
等问题
调用Object.prototype.toString()
比访问构造函数重。name
因为没有从某种类型到字符串的转换,我相信构造函数和构造函数都是成员变量,而不是getter
,这意味着在检索所述名称时不会调用其他函数。类似的事情是