背景:我正在阅读在线书籍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]));
感谢您阅读本文,非常感谢任何帮助或指导!
答案 0 :(得分:1)
正如我在评论中所说:
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]));
答案 1 :(得分:0)
首先,splice
是方法。
array.splice(1)
代替array.splice[1]
。
并在数组=== []。
中使用array.length == 0如果两个对象是不同的对象,则===运算符被视为false,即使所有元素都相同。