在JavaScript中通过递归继承构造序列/链表
Constructing a sequence/linked list through inheritance recursively in JavaScript
背景:我正在阅读在线书籍Eloquent JavaScript,第6章中的一个练习提到"Sequence"的行为类似于链表。这里是练习的链接,我已经复制了一些相关的文本:
另一个解决方案是避免改变对象的状态。您可以公开一种方法来获取当前元素(不推进任何计数器),另一种方法用于获取一个新序列,该序列表示当前元素之后的剩余元素(或者如果达到序列的末尾,则提供一个特殊值)。
我试图通过在接口类中递归地调用实现类的(ArraySeq)构造函数来构建序列。然而,当在节点上运行测试时,我得到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
作为一个构造函数,但你没有调用它作为一个构造函数。用new Sequence
代替Sequence.call
-
相反,您调用
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]));
首先,splice
是方法。
array.splice(1)
代替array.splice[1]
。
和使用数组。Length == 0 in array === [].
如果两个对象是不同的对象,则===运算符被视为假,即使所有元素都相同。
- 删除时出现Javascript链表问题
- JS中的专用链表
- 如何将 hasNext() 和 hasPrevious() 方法用于 Node 的“智能列表”链表模块
- JavaScript:用于查找链表节点的递归函数返回错误的节点
- JavaScript 如何处理传递给与这个链表示例相关的函数的对象
- 若模型是基于RubyonRails4上的单表继承创建的,那个么如何制作下拉列表
- 如何在javascript中实现函数调用的任意链表
- 链表与字典数组
- 在链表中循环
- Javascript:检测并从循环链表中删除一个循环
- 反转链表的时间复杂性
- 用javascript对链表进行分区
- 链表的javascript循环
- 为什么这个javascript add()函数用于链表返回节点?
- jQuery移动链表pageInit(),而不是$(document).ready()
- 如何在承诺链中继承数据而不创建闭包
- JS将数组转换为json链表
- 实现环回类表继承
- 转换数组到链表-从雄辩的Javascript
- 在JavaScript中通过递归继承构造序列/链表