在构造函数中的原型闭包 [英] prototype closure in the constructor

查看:165
本文介绍了在构造函数中的原型闭包的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更新:

这种实现方式太糟糕了, 。

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.

但有些东西不太好:


  1. 确保 不引用 this

  2. A.prototype.myFunc 随着对象创建的增长(更深)。

  3. 由于每个 var myFunc 仍由引用A.prototype.myFunc ,即使在调用引退并清除对对象的所有外部引用后,仍有疑问,它可能仍然存活在gc来临时。

  4. 我的测试环境有限,很高兴知道此实施是否存在潜在风险。

  1. It needs an extra function to ensure that not reference to this.
  2. A.prototype.myFunc is growing up(deeper) with the object creation afterwards.
  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.
  4. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆