是否可以确定使用object创建的对象.create继承了JavaScript中的Array

Is it possible to determine if an object created with Object.create inherits from Array in JavaScript?

本文关键字:继承 create 对象 JavaScript Array 中的 创建 object 是否      更新时间:2023-09-26

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

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

但是感觉有点粗糙。有没有更清晰的方法?

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

ECMAScript 5在javascript中引入了Array.isArray(),它提供了一种可靠的检查方法。对于旧的浏览器,我们通过(引用自本书)

来修复这个问题。
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(在铬测试)。我想出了一个可行的方法:

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); 

有关从Array继承时的问题的详细说明,请参阅http://perfectionkills.com/how-ecmascript-5-still-does-not-allow-to-subclass-an-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 .

如何检查构造函数?

function inherits(obj, proto) {
    return obj.constructor === proto.constructor;
}
inherits(Object.create(Array.prototype), Array.prototype);  // true

它的功能就像一个数组,无论如何,它都是一个数组

。它没有自动更新的length属性。查看这篇文章,为什么不可能创建Array的子类。

是否有办法弄清楚一个对象是否继承了一个特定的原型?我想你可以通过原型进行迭代,但感觉有点粗糙。

就是这么做的。比自编写函数更简洁的方法是使用instanceof操作符:

arr instanceof Array; // true