在Javascript中,如何使数组具有可实例化的自定义行为?

在Javascript中,如何使数组具有可实例化的自定义行为?,javascript,prototype,prototypal-inheritance,Javascript,Prototype,Prototypal Inheritance,我需要一种圆形阵列。除了一个例子,我什么都能用。我不知道如何使它成为实例。我的意思是,我希望它以以下方式工作: var arr = ['a', 'b', 'c', 'd']; // it's kind of pseudo-code arr.getNext(); // gives a arr.getNext(); // gives b arr.getNext(); // gives c arr.getNext(); // gives d arr.getNext(); // gives a arr

我需要一种圆形阵列。除了一个例子,我什么都能用。我不知道如何使它成为实例。我的意思是,我希望它以以下方式工作:

var arr = ['a', 'b', 'c', 'd']; // it's kind of pseudo-code 
arr.getNext(); // gives a
arr.getNext(); // gives b
arr.getNext(); // gives c
arr.getNext(); // gives d
arr.getNext(); // gives a
arr.getNext(); // gives b
// and so on
我知道我可以创建包含数组的对象并对其进行迭代,但我很确定我可以用另一种方法来实现

问题是我需要该对象的几个实例。如果这只是我能做的一个例子:

var arr = ['a', 'b', 'c', 'd'];
arr.getNext = function() {
  // ... I got this stuff working
}

如何允许创建此类自定义数组的多个实例?

您可以将getNext方法添加到数组原型中,如下所示:

Array.prototype.getNext = function ()
{
....
}

然后,您可以对创建的任何数组调用此方法。

您可以将getNext方法添加到数组原型中,如下所示:

Array.prototype.getNext = function ()
{
....
}
然后,您可以在创建的任何阵列上调用此方法。

您可以扩展原型,以便能够在阵列的所有实例中使用它:

请注意,这会修改阵列。

您可以扩展原型,使其能够在阵列的所有实例中使用:

请注意,这会修改数组。

即使您可以使用扩展array.prototype来创建不可枚举的属性,根据您的实际需要,另一种解决方案也可能很有趣

您可以定义一个函数,该函数返回数组上的迭代器:

function iter(arr) {
    var index = -1;

    return {
        next: function() {
            index = (index + 1) % arr.length;
            return arr[index];
        }
    };
}
用法:

var it = iter(arr);
it.next();
即使您可以使用扩展Array.prototype来创建不可枚举属性,根据您的实际需要,另一种解决方案也可能很有趣

您可以定义一个函数,该函数返回数组上的迭代器:

function iter(arr) {
    var index = -1;

    return {
        next: function() {
            index = (index + 1) % arr.length;
            return arr[index];
        }
    };
}
用法:

var it = iter(arr);
it.next();

一个小问题:您需要扩展阵列原型吗?Array.getNext=函数{…}有什么不同?是的,如果这样做,则需要扩展原型。getNext将对象附加到全局数组对象,而不是每个实例,因此该对象的上下文将丢失。但是你总是可以创建自己的函数并传入一个数组,比如函数getNextarr{…}哦,当然,巧合的是,我在看一段代码,它做了一个类似的Object.func=…,想知道这有什么不同,但后来意识到它并不意味着要添加到所有的对象实例中。我不想知道对于所有数组,这就是我不想扩展Array.prototype的原因,我的问题从这里开始:一个小问题:您需要扩展Array.prototype吗?Array.getNext=函数{…}有什么不同?是的,如果这样做,则需要扩展原型。getNext将对象附加到全局数组对象,而不是每个实例,因此该对象的上下文将丢失。但是你总是可以创建自己的函数并传入一个数组,比如函数getNextarr{…}哦,当然,巧合的是,我在看一段代码,它做了一个类似的Object.func=…,想知道这有什么不同,但后来意识到它并不意味着要添加到所有的对象实例中。我不想知道对于所有数组,这就是我不想扩展Array.prototype的原因,我的问题就从这里开始:不幸的是,我不希望它出现在我所有的数组对象中。这就是我在如何编写它时遇到的问题。@grafthez在所有数组对象中使用此函数有什么问题?在原型中声明此函数不会对数组的行为造成任何更改。您只能获得可以使用的附加函数。@ShaiAharoni向Object.prototype或Array.prototype添加内容时,myArray中的内容会随着getNext函数的出现而发生变化。这可能会破坏试图使用您的代码的人的代码。即使在数组中做一些事情不是一个好主意,但这并不能阻止其他人尝试这样做。Felix通过提到Object.defineProperty将enumerable设置为false解决了这个问题,但在我看来,这个特殊的问题最好通过他的答案中提到的iter函数来解决。不幸的是,我不希望它出现在我所有的数组对象中。这就是我在如何编写它时遇到的问题。@grafthez在所有数组对象中使用此函数有什么问题?在原型中声明此函数不会对数组的行为造成任何更改。您只能获得可以使用的附加函数。@ShaiAharoni向Object.prototype或Array.prototype添加内容时,myArray中的内容会随着getNext函数的出现而发生变化。这可能会破坏试图使用您的代码的人的代码。即使在数组中做一些事情不是一个好主意,但这并不能阻止其他人尝试这样做。Felix通过提到Object.defineProperty将enumerable设置为false来解决这个问题,但在我看来,这个特殊的问题最好通过他的答案中提到的iter函数来解决。哦,这太酷了。我从来没有这样想过。谢谢!哦,那太酷了。我从来没有这样想过。谢谢!