我以为我有一个this引用传递到Javascript闭包中的私有函数,我想错了
I thought I had a this reference passed into a private function in a Javascript closure, I thought wrong
我认为代码解释得很好。我使用闭包来保持称为reverseAll
私有的方法。reverseAll
是递归的,但我认为你不需要担心这个。我试图在reverseAll
函数中引用this.head
,但我发现它是undefined
。所以我传递了一个对this.head
的引用,并通过递归调用继续传递它。唉,这不是命中注定的。我可以把reverseAll
方法从闭包中拉出来,我将有一个对this.head
的引用。但我想知道为什么我传递的this.head
引用不是"引用的副本"或"指针的副本",如果你喜欢Javascript,当你将对象传递给函数时。顺便说一下,this.head
是node
对象。
这里是代码(引用jQuery是因为Stackoverflow片段"IDE"失败时,行var obj = new LinkedList();
,所以我添加了一个文档。准备好了,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>
当前实现的实际问题在于赋值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] }
>
您的成员值this.head
将被您在返回对象中定义的函数覆盖!
head: function()
{
return this.head;
}
被添加到原型。
然后实例化LinkedList,原型用于扩展this
。这一点。然后将Head替换为function。
最好是将函数重命名为gehead,例如
- 我怎么把范围弄错了?无法从jQuery访问此函数;.在“上”;
- JavaScript 错误:未捕获的类型错误:undefined 不是第 4 行的函数;我不知道我做错了什么
- 在 c#.net 中执行 javascript 函数.我做错了什么
- Javascript Date.getTime 函数没有返回正确的值,或者我做错了什么
- D3 TypeError: link.exit 不是函数 link.exit().remove();我做错了什么
- 当单击jquery-ui选项卡时,我需要运行一个函数,我做错了什么
- 我在nodejs/mongodb上的更新函数上做错了什么
- 回调不是一个函数:我做错了什么
- 函数仍在异步调用.我做错了什么
- 我有一个javascript函数,我可以'Don't tell what I;我做错了
- 我的谷歌电子表格脚本只运行一个函数.我把剧本编错了吗
- 在类的每个项上运行jquery函数,我做错了什么
- 我以为我有一个this引用传递到Javascript闭包中的私有函数,我想错了
- onComplete属性必须是javascript函数名;我打错了什么?
- Backbone.Model.extend()不是一个函数,我做错了什么?
- appendChild不是一个函数-我做错了什么?
- AngularJS-链接函数中的作用域被重置,我做错了什么
- 什么'错了我的ajax函数获取图像
- 中值JS函数.错了
- 使用JavaScript函数作为“类”:我在这里做错了什么?