奇怪的数组对象-JavaScript

时间:2018-08-28 03:36:28

标签: javascript

与其他编程语言相比,数组在JavaScript中是相当有用的东西,而且并非没有完整的怪癖。

包括这个:

// Making a normal array.
var normalArray = [];
normalArray.length = 0;

normalArray.push(1);
normalArray[1] = 2;

normalArray; // returns [1, 2]
normalArray.length // returns 2

是的,以上是我们大家都知道的制作数组并用元素填充它们的方法,对吗? (暂时忽略normalArray.length = 0部分)

但是为什么将相同的序列应用于不是纯粹数组的对象时,它看起来有点不同,并且其length属性却有些偏离呢?

// Making an object that inherits from the array prototype (i.e.: custom array)
var customArray = new (function MyArray() {
    this.__proto__ = Object.create(Array.prototype);
    return this
});
customArray.length = 0;

customArray.push(1);
customArray[1] = 2;

customArray; // returns [1, 1: 2]
customArray.length // returns 1

不能完全确定这里发生了什么,但是有些解释将不胜感激。

3 个答案:

答案 0 :(得分:1)

您要创建的数组不是纯数组(您可能已经知道)。它基本上是一个JavaScript对象,应该表现得像一个对象。

在将对象像数组一样对待时,您可以自行维护所有像数组一样的特征。

您特别需要为其分配一个length属性,并且您正确地做到了。

接下来,应该使用push中的Array.prototype方法将一个元素插入到数组中并增加length属性(如果有),因此将0递增为1。您去了,length现在是1。

接下来,您使用Object的属性赋值的文字表示法,类似于customArray['someProperty'] = 1之类的东西。

虽然使用文字表示法,但是没有调用Array.Prototype中的任何方法,因此customArray对象从不知道它的行为必须像Array,并且length属性不受影响。它的行为就像一个对象,您将得到所得到的。

请记住length只是Array类的一个属性,此属性由Array上的每个方法适当地递增和递减。

注意:不建议使用类似数组的对象,完全由您来维护此类对象的索引和其他数组内容。

答案 1 :(得分:1)

这可能不是一个完美的答案,但是根据我对Javascript数组的理解,它们与通常的对象有些不同。 (主要是因为它保留了length属性,而Objects没有)。

因此,如果我们以您的代码为例:

var normalArray = [];

这是在Javascript中创建数组的正确方法。但是下一个呢?

var customArray = new (function MyArray() {
    this.__proto__ = Object.create(Array.prototype);
    return this
});

它们相同吗?让我们看看。

Array.isArray(normalArray); // true -> [object Array]
Array.isArray(customArray); // false -> [object Object]

因此很明显,尽管您继承了数组原型,但实际上并没有创建Array类型的对象。它只是创建一个普通的JS对象,但带有继承的数组函数。这就是为什么在使用customArray.push(1);设置值时会更新长度的原因。

但是由于您的customArray只是一个常规对象,而对于常规JS对象,[]表示法用于设置属性,因此不会更新长度(因为Objects没有length属性)

希望很清楚:)

答案 2 :(得分:0)

据我所知,您的功能存在问题:

return this

应该是

return (this);

只需修复您可能遇到的任何潜在错误。另一件事是您没有使用var关键字来声明customArray。这些错误可能会破坏您的代码。