Javascript:在闭包中,可以在实例化后添加私有成员(var`s)吗?

时间:2014-10-18 15:08:14

标签: javascript closures

可以"私人"实例化后,成员(vars)会被添加到闭包中吗?

我想我在下面的关闭中理解了这一点(如果我错了,请纠正我!):

  • this.x可用"公开"

  • var y不公开,但可以通过this.y()

  • 访问
  • new Closure()之后,我可以添加一个新的" public"像这样:

    var c=new Closure();
    c['z']=25;
    console.log(c.z);  // z is a dynamically added public member
    

所以......有没有办法在" new-ing"之后动态添加私有成员(var)及其获取/设置功能。关闭?

var Closure=( function(){

    function Closure(x){
        // "public" member
        this.x=x;
    };

    // "private" member backing variable
    var _y=0;

    // get/set private member
    Closure.prototype.y=function(newValue){
        if(newValue){
            _y=newValue;
            return(this);
        }else{
            return(_y);
        }
    };

    // return
    return(Closure);

} )();


var c=new Closure(10,15);

// Can I add var _z and it's get/set function at this point?

2 个答案:

答案 0 :(得分:1)

  

var y无法公开

  

但可以通过this.y()

访问

没有。 this通常是一个对象,.y始终是属性引用。它永远不能用于访问y 变量

  

有没有办法在“new-ing”Closure之后动态添加私有成员(var)及其get / set函数?

没有。调用Closure()函数(在您的情况下作为构造函数)时,其所有变量(x)的范围已确定,无法修改。

同样的事情适用于IIFE,其执行引入了后来解决的本地Closure_y变量。

然而,你可以做的是添加一个 new getter / setter对,它有自己的范围(它可能有其他“私有”变量),但是不可能访问{{ 1}}从外部变量或操纵它所在的范围。

_y

此处无法修改function Scope(x, y) { // "public" member this.x = x; // private "member" var _y = y; // accessors: this.setY = function(newValue) { _y = newValue; }; this.getY = function() { return _y; }; // '_y' is still accessible here ^^ // through closure of the two functions, which can access their parent scope } var c = new Scope(10, 15); c.x // 10 c.getY() // 15 (以及_yx)所在的范围。但是,我们可以向y添加一个新字段,即使其变量不在同一范围内:

c

答案 1 :(得分:0)

是。有点。您可以创建一个私有对象或数组,并提供添加到它的方法。

使用WeakMap

function myClosure() {
    var hidden = new WeakMap();
    var obj = {
        addPrivate: function(name, value) {
            var privateData = hidden.get(this);
            privateData[name] = value;
        }
    }
    hidden.set(obj, {});
    return obj;
}

var foo = myClosure();
foo.addPrivate('bar', 7);
foo.getBar = function() {
    var priv = hidden.get(this);
    return priv.bar;
}
foo.getBar(); //7

更好的问题是你应该这样做吗?答案通常是否定的。我认为值得上述所有chichanery不便的唯一一次是当我有一个应用程序核心对象时,我逐步使用异步扩展脚本进行增强(如果我不需要担心,我会使用WeakMap表单旧的浏览器,如果我这样做,我使用嵌套的obj文字。)