JavaScript中是否有不同类型的Array?如何规避非标准数组问题?
问题描述
这是两个由相同字符串组成、但类型不同的“数组”的控制台输出。我不清楚它们的生成来源(项目中有大量非我编写的代码),但可以确定只有Object2是真实的Array实例,因为它自带length属性,调用Object1.length返回的结果是0。
尽管控制台中Object1被标注为Array,但它实际是带有数字下标的普通对象。我该如何避免用到Object1这类伪数组,保证所有用到的数组都和Object2一致?
Object1 Array {0: 'ABC', 1: 'IJK', 2: 'XYZ'} 0: "ABC" 1: "IJK" 2: "XYZ" [[Prototype]]: Array(0) Object2 (3) ['ABC', 'IJK', 'XYZ'] 0: "ABC" 1: "IJK" 2: "XYZ" length: 3
补充说明1
Object1和Object2只是本例中使用的变量名。
调用Array.isArray(Object1)返回false,而Array.isArray(Object2)返回true。这种被控制台标记为Array的对象是如何创建的?[该问题已由评论区用户CRice解答,见补充说明3]
补充说明2
代码运行在老旧的AngularJS项目中,以下是数据来源的相关代码。Object1对应的变量就是下方模型中本应为数组的someArray,它通过适配器初始化。Object2是传统的内联创建方式:Object2 = [];
Model代码
define([], function () { return [ function () { function SomeObjectModel(someArray) { this.someArray = someArray; } SomeObjectModel.prototype.serialize = function () { return { someArray: this.someArray, }; }; SomeObjectModel.build = function (data) { return new SomeObjectModel(data.someArray); }; return SomeObjectModel; }, ]; });
Adapter代码
var serializedSomeObject = someObjectInstance.serialize(); return $http({ method: 'PUT', url: 'someUrl.com/api', data: serializedSomeObject, }).then(function (response) { return SomeObjectModel.build(response.data); });
补充说明3
@CRice指出,以下代码可以复现这种被标注为Array但行为不符合预期的Object1实例:
var o = { 0: 'ABC', 1: 'IJK', 2: 'XYZ' }; Object.setPrototypeOf(o, Array.prototype); console.log(o);
补充说明4
我不清楚为什么序列化后再反序列化会导致这个问题,但我的解决方案是遍历Object1的属性,将它们推入新数组即可。以下是我将Object1转换为Object2的实现:
var Object2 = []; var attr = Object.getOwnPropertyNames(Object1); for(var i=0; i<attr.length; i++){ Object2.push(Object1[attr[i]]); } console.log(Object2);
感谢CRice帮我在控制台复现了该问题!
内容的提问来源于stack exchange,提问作者Zachary
相关产品推荐
相关产品推荐

