7

识别哪些对象是JavaScript中的复杂对象,并找出哪些对象是数组,这有点像hacky 的解决方案。幸运的是,它设法在以下两种情况下工作:

Object.prototype.toString.call([]);           // [object Array]
Object.prototype.toString.call(new Array());  // [object Array]

太好了,[object Object]看不到!可悲的是,这种方法仍然失败了:

var arr = Object.create(Array.prototype);
Object.prototype.toString.call(arr);          // [object Object]

这令人沮丧,所以至少可以这么说。我的arr对象具有数组的所有方法,它的功能类似于数组,并且出于所有目的,它一个数组。然而 JavaScript 并没有提供工具来识别它。

有什么方法可以判断一个对象是否继承自一个特定的原型?我想你可以像这样遍历原型:

function inherits(obj, proto) {
    while (obj != null) {
        if (obj == proto) return true;
        obj = Object.getPrototypeOf(obj);
    }
    return false;
}

inherits(Object.create(Array.prototype), Array.prototype);  // true

但感觉有点hacky。有没有更清洁的方法?

4

5 回答 5

2

instanceof运算符怎么样?它会true为您的所有情况返回:

[] instanceof Array //true
new Array() instanceof Array //true
Object.create(Array.prototype) instanceof Array //true

然而:

Object.create(Array.prototype) instanceof Object //also true

所以要小心。

于 2013-05-24T06:24:02.537 回答
2

ECMAScript 5 引入Array.isArray()了 javascript,它提供了一种可靠的检查方式。对于较旧的浏览器,我们通过(引自本书)解决了这个问题

function isArray(value) {
    if (typeof Array.isArray === "function") {
         return Array.isArray(value);
    } else {
         return Object.prototype.toString.call(value) === "[object Array]";
    }
}

但是我刚刚发现内置功能Array.isArray在我们使用时无法正常工作Object.create(在 chrome 中测试)。我想出了一个可行的方法:

function isArray(value) {
     if (typeof value === "undefined" || value === null) {
          return false;
     }
     do {
          if (Object.prototype.toString.call(value) === "[object Array]") {
               return true;
          }
          value= Object.getPrototypeOf(value);
     } while (value);

     return false;
}

用它:

var arr = Object.create(Array.prototype);
var arr1 = Object.create(Object.create(Array.prototype));
var arr2 = new Array();
var arr3 = [];
isArray(arr); 
isArray(arr1); 
isArray(arr2); 
isArray(arr3); 
于 2013-05-24T06:33:34.207 回答
2

请参阅http://perfectkills.com/how-ecmascript-5-still-does-not-allow-to-subclass-an-array/了解从 Array 继承的问题的明确说明。

无论如何,在最简单的情况下,你在哪里

var sort_of_an_array = Object.create(Array.prototype);

你可以检查使用isPrototypeOf

Array.prototype.isPrototypeOf(sort_of_an_array)

请参阅https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isPrototypeOf

于 2013-07-04T15:54:13.537 回答
0

检查构造函数怎么样?

function inherits(obj, proto) {
    return obj.constructor === proto.constructor;
}

inherits(Object.create(Array.prototype), Array.prototype);  // true
于 2013-05-24T06:38:27.427 回答
0

它的功能就像一个数组,并且出于所有目的,它是一个数组

不,它没有自动更新length属性。请参阅这篇文章,为什么子类是完全不可能的Array

有什么方法可以判断一个对象是否继承自一个特定的原型?我想你可以遍历原型,但感觉有点老套。

这就是如何做到这一点。比自写函数更简洁的方法是使用instanceofoperator

arr instanceof Array; // true
于 2013-07-04T15:59:10.800 回答