在构造函数中的原型闭包 [英] prototype closure in the constructor
问题描述
更新:
这种实现方式太糟糕了, 。
This kind of implementation is simply bad, and I've removed that answer.
我刚刚回答了此问题。 OP要求的私人成员的解决方案,只能通过原型方法访问。对于我的回答,我不建议这样做,但提出其可能性的代码。 (对不起,我对标题没有好处..)
I just answered this question. The OP asked for the solution of a private member which can only be accessible by prototype methods. For my answer, I would not suggest to do that but propose the code of its possibility. (And sorry, I do not have a good idea with the title .. )
-
代码
Code
function A(prop1) {
var myFunc=A.prototype.myFunc;
var that=this;
A.prototype.myFunc=function () {
if (this===that) {
alert(prop1); // do something
}
else {
myFunc.call(this);
}
};
this.retire=function () {
that=undefined;
};
}
A.prototype.myFunc=function () {
};
var a1=new A(1);
var a2=new A(2);
var a3=new A(3);
a1.myFunc();
a2.myFunc();
a3.myFunc();
a2.retire();
a1.myFunc();
a2.myFunc();
a3.myFunc();
// ..
我们可以看到,如果任何其他原型方法访问 prop1
,将需要重复此模式。我曾经想过使用一个私人数组来实现它,但这个代码似乎明显更短。
As we can see if any other prototype methods would access prop1
, will need to repeat this pattern. I've ever thought about to use a private array to achieve it, but this code seems significantly shorter.
但有些东西不太好:
- 确保
this
。 -
A.prototype.myFunc
随着对象创建的增长(更深)。 - 由于每个
var myFunc
仍由引用A.prototype.myFunc
,即使在调用引退
并清除对对象的所有外部引用后,仍有疑问,它可能仍然存活在gc来临时。 - 我的测试环境有限,很高兴知道此实施是否存在潜在风险。
- It needs an extra function to ensure
that
not reference tothis
. A.prototype.myFunc
is growing up(deeper) with the object creation afterwards.- As every
var myFunc
are still referenced byA.prototype.myFunc
, there's a doubt even after invokedretire
and clean up all outter reference to an object, it might still alive when the gc comes. - I have limited testing environment and be pleasure to know if there's potential risk with this implementation.
所以我认为这个问题的答案可能是:
So I think an answer to the question could be:
。一个更可行的方法来改变构造函数中的原型方法,以实现私有成员只能在原型方法中访问。
A. A more feasible approach to alter the prototype methods in the constructor to achieve that the private members can only be accessible in prototype methods.
B。另一种方法来实现同样的事情,并且代码尽可能简单。
B. Another method to achieve the same thing, and the code is as simple as possible.
这也将非常感谢指出我的误解的闭包和垃圾回收在你的答案。
It would also be greatly appreciated to point out my misunderstanding of the closures and the garbage collection within your answers.
推荐答案
1。它需要一个额外的函数来确保不参考这个。
1 . It needs an extra function to ensure that not reference to this.
没有解决方法。 每个实例化中
,实例本身是可以访问 A.prototype.myFunc
捕获直接,
更多的对象涉及只会使事情更糟; retire
方法已经是解开引用的最简单的方法。
There isn't a workaround. that
is captured by A.prototype.myFunc
within each instantiation, and the instance itself is the object which can access that
directly, more objects involve would just make things worse; the retire
method is already the simplest way to untangle the reference.
2。 A.prototype.myFunc随着对象创建的增长(更深)。
2 . A.prototype.myFunc is growing up(deeper) with the object creation afterwards.
这只是潜在风险。 A.prototype.myFunc
与递归方法类似,但实际上不是。它调用前面的 myFunc
并检查实例的身份。对于少数情况它不是一个问题,但对于大量的实例,不断增长的深度将最终导致堆栈溢出。
This is just the potential risk. A.prototype.myFunc
is made similar to a recursive method, but in fact it isn't. It calls to the previous myFunc
and check the instance for its identity. For a few instances it isn't a problem, but for a plenty of the instances, the growing depth will finally cause stack overflow.
由于实现将需要一个机制来清除,使调用更深入只是使用一个数组来保存引用,需求。
As the implementation will whatever need a mechanism for cleanning up, to make the calls deeper gains nothing than just use an array to hold the references, and to clean up on-demand.
3。由于每个var myFunc仍然由A.prototype.myFunc引用,即使在调用退出并清除了对对象的所有引用之后,仍然有一个疑问,它可能仍然存活在gc来临时。
3 . As every var myFunc are still referenced by A.prototype.myFunc, there's a doubt even after invoked retire and clean up all outter reference to an object, it might still alive when the gc comes.
事实是 var myFunc
code> A.prototype.myFunc 将仍然活着,即使gc来收集garbages。几乎不可能使得引用 myFunc
被释放,因为它是一个链接调用,深层调用和浅调用不具有彼此的可见性,因此它们中没有一个能够修改用于跳过级别的调用链; unset myFunc
会破坏链。试图解决这个问题的任何伎俩会涉及更多的对象,这可能会增加成本或是一个过度。
The fact is var myFunc
which is captured by A.prototype.myFunc
will still alive even when the gc comes to collect garbages. There is almost impossible to make the reference to myFunc
be released, since it's a chained invocation, the contexts of a deeper call and the shallow call do not have the visibility to each other, thus none of them are able to modify the chain of invocation for skipping a level; unset myFunc
would just break the chain. Any trick trying to solve this would involve more objects, that may either increase the cost or being an overkill.
4。我有限的测试环境,很高兴知道这个实现是否存在潜在风险。
4 . I have limited testing environment and be pleasure to know if there's potential risk with this implementation.
作为第2点的答案,当使用它创建大量对象时,可能会导致堆栈溢出。
As the answer to the bullet point 2, it may cause stack overflowing when a lot of object are created with it.
这篇关于在构造函数中的原型闭包的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!