因此,我认为代码解释得非常好。我使用一个闭包来保持一个名为reverseAll
的方法是私有的。 reverseAll
是递归的,但你不必担心我的想法。我想在this.head
函数中引用reverseAll
,但我发现它是undefined
。所以我传递了对this.head
的引用并继续通过递归调用。唉,这不是故意的。我可以将reverseAll
方法拉出闭包,我将引用this.head
。但是我想知道为什么我传入的this.head
引用不是“引用的副本”或“指针的副本”,如果您希望Javascript在将对象传递给函数时执行。顺便提一下,this.head
是node
个对象。
这是代码(对jQuery的引用是因为Stackoverflow代码段“IDE”在联机var obj = new LinkedList();
时失败,所以我添加了一个document.ready,jQuery不需要除此之外的任何原因:
function LinkedList() {
this.head = null;
};
LinkedList.prototype = (function () {
function reverseAll(current, prev, theHead) {
if (!current.next) { //we have the head
console.log('ending recursion, new head!!');
console.log('we have a refence to this.head in theHead or so I thought:');
console.log(theHead);
theHead = current;
theHead.next = prev;
console.log('theHead has a new "pointer":');
console.log(theHead);
return;
}
var next = current.next;
current.next = prev;
//keep passing the theHead reference through recursion
reverseAll(next, current, theHead);
};
return {
constructor: LinkedList,
reverse: function () {
console.log('clone head to iterate and change');
console.log('but also pass in reference of this.head obj as this.head is a node obj and this.head will be undefined in reverseAll()');
var headClone = JSON.parse(JSON.stringify(this.head));
reverseAll(headClone, null, this.head);
}
}
})();
LinkedList.prototype.add = function(value) {
var node = {
value: value,
next: null
};
var current;
if (this.head === null) {
this.head = node;
} else {
current = this.head;
while (current.next) {
current = current.next;
}
current.next = node;
}
return node;
}
LinkedList.prototype.remove = function(node) {
var current, value = node.value;
if (this.head !== null) {
if (this.head === node) {
this.head = this.head.next;
node.next = null;
return value;
}
//find node if node not head
current = this.head;
while (current.next) {
if (current.next === node) {
current.next = node.next;
return value;
}
current = current.next;
}
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script>
$(function() {
var obj = new LinkedList();
for (var i = 1; i <= 10; i++) {
obj.add(i);
}
console.log('about to call obj.reverse()!');
console.log('obj.head:');
console.log(obj.head);
obj.reverse();
console.log('obj instance obj.head after reverse call, it has not changed!!:');
console.log(obj.head);
});
</script>
答案 0 :(得分:1)
当前实施的实际问题在于作业theHead = current
。这对您LinkedList
的实例没有任何影响。一个简单的解决方法是将this
作为reverseAll(current, prev, instance)
的最后一个参数传递,并将有问题的分配更改为:
instance.head = current;
current.next = prev;
但是,我相信更好的代码设计可以帮助避免这个问题。将reverseAll
放在reverse
内。首先它属于那里,因为它不用于任何其他目的,其次你甚至不需要将this
传递给它,如果你使用名称替换var self = this;
,则从闭包中使用它。后者是在其他地方使用的可取模式,它有助于避免琐碎的错误:
function LinkedList() {
this.head = null;
}
LinkedList.prototype.reverse = function() {
var self = this;
var reverseAll = function(current, prev) {
var exitCondition = !current.next;
var next = current.next;
current.next = prev;
if (exitCondition) {
self.head = current;
return;
}
reverseAll(next, current);
};
// FIXME this is ugly, but unrelated, so keep it
var headClone = JSON.parse(JSON.stringify(self.head));
reverseAll(headClone, null);
};
// remove and add prototypes as in the original
节点
> a = new LinkedList();
LinkedList { head: null, reverse: [Function] }
> a.add(1);
{ value: 1, next: null }
> a.add(2);
{ value: 2, next: null }
> a
LinkedList {
head: { value: 1, next: { value: 2, next: null } },
reverse: [Function] }
> a.reverse();
undefined
> a
LinkedList {
head: { value: 2, next: { value: 1, next: null } },
reverse: [Function] }
>
答案 1 :(得分:0)
您的成员值this.head
将被您在返回对象中定义的函数覆盖!
head: function()
{
return this.head;
}
被添加到原型中。
然后您实例化LinkedList,原型用于扩展this
。然后将this.head替换为函数。
您可以做的最好的事情是将函数重命名为getHead。