到目前为止,我依靠Object.prototype.toString.call(x)
来区分Javascript中的不同本机对象类型,特别是数组。
如果你是数组的子类,你会得到一些奇怪的行为:
function Ctor() {}
Ctor.prototype = Object.create(Array.prototype);
var x = new Ctor();
x.push(1);
Object.prototype.toString.call(x); // [object Object]
可能这在ES5规范中有记录(在ES6中不再是问题),但我认为这是当前版本语言的一个怪癖。我调整了相应的功能如下:
function objTypeOf(deep, type) {
return function _objTypeOf(x) {
do {
if (Object.prototype.toString.call(x).slice(8, -1).toLowerCase() === type) return true;
x = Object.getPrototypeOf(x);
} while(deep && x !== null);
return false;
};
}
var arr = objTypeOf(false, "array"),
arrP = objTypeOf(true, "array"); // array prototype
console.log(arr(x)); // false
console.log(arrP(x)); // true
objTypeOf
检查当前对象和整个原型链,直到存在类型匹配。即使只有一个原型与预期类型匹配,它也会接受一个对象。 objTypeOf
不是基于原型身份,而是基于字符串(缺乏身份)。
我现在想知道在使用Object.prototype.toString
时是否还有其他边缘情况需要特殊处理?
答案 0 :(得分:3)
您的问题不在于Object.prototype.toString
,而在于您尝试subclass arrays。它只是不起作用,并且toString
正确地告诉您无法创建数组。它只是一个在其原型链中具有Array.prototype
的对象(如果这是你所关心的,请使用instanceof Array
)。
无论如何,要回答你的标题问题:
使用Object.prototype.toString时的边缘情况是什么?
主机对象。尽管看起来像是一个本地JS对象,但所有东西都可能会返回您没想到的任何[[Class]]值。甚至有些可调用对象不报告Function
的情况。