使用Object.prototype.toString时的边缘情况是什么?

时间:2015-12-18 10:54:17

标签: javascript arrays tostring

到目前为止,我依靠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时是否还有其他边缘情况需要特殊处理?

1 个答案:

答案 0 :(得分:3)

您的问题不在于Object.prototype.toString,而在于您尝试subclass arrays。它只是不起作用,并且toString正确地告诉您无法创建数组。它只是一个在其原型链中具有Array.prototype的对象(如果这是你所关心的,请使用instanceof Array)。

无论如何,要回答你的标题问题:

  

使用Object.prototype.toString时的边缘情况是什么?

主机对象。尽管看起来像是一个本地JS对象,但所有东西都可能会返回您没想到的任何[[Class]]值。甚至有些可调用对象不报告Function的情况。