背景:我正在阅读在线书籍Eloquent JavaScript,第6章中的一项练习提到“序列”的行为类似于链接列表。 Here是练习的链接,我已经复制了一些相关的文本:
另一种解决方案是避免更改对象的状态。您可以公开一种用于获取当前元素的方法(不增加任何计数器),以及一种用于获取一个新序列的方法,该序列表示当前元素之后的剩余元素(如果到达序列的末尾,则为特殊值)。
我正在尝试通过在接口类中递归调用实现类的(ArraySeq)构造函数来构建Sequence。但是,在节点中运行测试时,我得到了TypeError: Cannot read property '0' of undefined at Sequence.ArraySeq
。
我已经复制并粘贴了(不完整的)实现:
/**
* Sequence interface
*/
function Sequence(current, rest) {
this.current = current;
this.rest = rest;
}
Object.defineProperty(Sequence.prototype, "end", {
get: function() {
return this.rest === undefined;
}
});
Sequence.prototype.next = function() {
return this.rest;
};
/**
* Array implementation of sequence
*/
function ArraySeq(array) {
if (array === []) {
Sequence.call(undefined, undefined);
} else {
Sequence.call(array[0], new ArraySeq(array.slice(1)));
}
}
ArraySeq.prototype = Object.create(Sequence.prototype);
/**
* Logs all elements in a Sequence
*/
function logSequence(sequence) {
while (sequence.rest !== undefined) {
console.log(sequence.current);
sequence = sequence.rest;
}
}
logSequence(new ArraySeq([1, 2]));
感谢您阅读本文,非常感谢您的帮助或指导!
最佳答案
正如我在评论中指出的:array.splice[1]
将为您提供不确定的信息。您需要array.slice(1)
-没有第一个元素的整个数组:slice
,而不是splice
。 array.splice(1)
将从数组中删除第二个元素,然后返回该元素-不是您想要的。
您将Sequence
写为构造函数,但没有将其称为构造函数。代替Sequence.call
,使用new Sequence
。
相反,您正在调用new ArraySeq
,但是ArraySeq
看起来不像构造函数。仅使用ArraySeq
,并使其返回内容(return new Sequence...
)。
使用if (!array.length)
测试数组是否为非空。 array === []
甚至array == []
都永远不会返回true,因为对象(以及数组)是根据对象标识而不是相等性进行比较的,而您只是创建了一个新对象(因此,不可能有同一个对象作为已经存在的东西)。
当然,没有定义ArraySequence
。应该是ArraySeq
,对吧?
有了这些更改,您的代码就可以工作。编辑:但是,练习希望ArraySeq
是一个对象,因此仍然需要更多工作...首先,“接口”不是对象。这就是对象的行为方式。我的练习是:
function ArraySeq(array) {
this.array = array;
this.index = 0;
}
Object.defineProperty(ArraySeq.prototype, "end", {
get: function() {
return this.index >= this.array.length;
}
});
Object.defineProperty(ArraySeq.prototype, "next", {
get: function() {
return this.array[this.index++];
}
});
/**
* Logs all elements in a Sequence
*/
function logSequence(sequence) {
while (!sequence.end) {
console.log(sequence.next);
}
}
logSequence(new ArraySeq([1, 2]));
这里的“接口”是
.end
和.next
。如果您想走报价的路线,则略有变化。这里的接口是.end
,.rest
和.value
:function ArraySeq(array) {
this.array = array;
}
Object.defineProperty(ArraySeq.prototype, "end", {
get: function() {
return this.array.length == 0;
}
});
Object.defineProperty(ArraySeq.prototype, "rest", {
get: function() {
return new ArraySeq(this.array.slice(1));
}
});
Object.defineProperty(ArraySeq.prototype, "value", {
get: function() {
return this.array[0];
}
});
/**
* Logs all elements in a Sequence
*/
function logSequence(sequence) {
while (!sequence.end) {
console.log(sequence.value);
sequence = sequence.rest;
}
}
logSequence(new ArraySeq([1, 2]));
关于javascript - 在JavaScript中通过继承递归构造序列/链接列表,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31306674/