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

后端 未结 5 1932
野的像风
野的像风 2021-01-12 12:59

Identifying which objects are which is complicated in JavaScript, and figuring out which objects are arrays has something of a hacky solution. Fortunately, it manages to wor

相关标签:
5条回答
  • 2021-01-12 13:14

    ECMAScript 5 has introduced Array.isArray() into javascript which provides a reliable way to check. For older browsers, we fix that by (quoted from this book)

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

    But i just found out the built-in function Array.isArray does not work correctly when we use Object.create (tested in chrome). I came up with a method that works:

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

    Use it:

    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); 
    
    0 讨论(0)
  • 2021-01-12 13:15

    How about an instanceof operator? It returns true for all your cases:

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

    However:

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

    So be careful.

    0 讨论(0)
  • 2021-01-12 13:19

    How about checking the constructor?

    function inherits(obj, proto) {
        return obj.constructor === proto.constructor;
    }
    
    inherits(Object.create(Array.prototype), Array.prototype);  // true
    
    0 讨论(0)
  • 2021-01-12 13:33

    it functions like an array, and for all purposes, it is an array

    No. It has no auto-updating length property. See this article why it's quite impossible to subclass Array.

    Is there any way to figure out if an object inherits from a particular prototype? I suppose you could iterate through the prototypes, but it feels a tad hacky.

    That's just how to do it. A cleaner approach than a self-written function would be to use the instanceof operator:

    arr instanceof Array; // true
    
    0 讨论(0)
  • 2021-01-12 13:37

    See http://perfectionkills.com/how-ecmascript-5-still-does-not-allow-to-subclass-an-array/ for the definitive exposition of the problems in inheriting from Array.

    Anyway, in the simplest case, where you are doing

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

    you can check using isPrototypeOf:

    Array.prototype.isPrototypeOf(sort_of_an_array)
    

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

    0 讨论(0)
提交回复
热议问题