2011-12-25 53 views
11

有没有办法从模块模式动态访问私有变量的公共功能? 测试1显示了我的意思与“动态访问”,但与公共变量是否可以动态访问模块模式中的私有变量?

var x = (function(){ 
    var x=0, y=2, z=5; 

    return { 
     toast: 123, 
     test1: function(arg){ 
      return this[arg]; 
     }, 
     test2: function(){ 
      // ?? 
     } 
    }; 
}()); 

console.log(x.test1("toast")); // 123 
console.log(x.test2("y")); // should return 2 

我结束了创建一个私有变量(一个对象)存储我的私有变量,所以我能够访问他们这样

privateVarStore[privateVarName] 

但有没有另一种解决方案呢?

回答

9

DEMO

是。

抱歉,让亚当Rackis但你可以(在邪恶)EVAL做到这一点:

var x = (function(){ 
    var x=0, y=2, z=5; 

    return { 
     toast: 123, 
     test1: function(arg){ 
      return this[arg]; 
     }, 
     test2: function(a){ 
      return eval(a) 
     } 
    }; 
}()); 

console.log(x.test1("toast")); // 123 
console.log(x.test2("y")); // should return 2 -> does return 2 

这是那些少数的例外情况eval应使用一个。

编辑,按照汉斯乙PUFAL建议(意见),你可以而且应该验证参数test2如下:

test2: function(a){ 
    return /^[$_a-z][$_a-z0-9]*$/i.test (a) ? eval(a) : undefined; 
} 
+3

为了避免安全问题,建议添加一个验证,即参数到test2确实是一个简单的变量:return/^ [$ _ a-z] [$ _ a-z0-9] * $/i.test(a)? eval(a):undefined; – HBP 2011-12-25 05:56:27

+0

@HansBPUFAL:好主意!我一定会把它加上 – qwertymk 2011-12-25 06:10:17

+1

+1,但是我能否提出另一种验证思路:如果你定义了一个列出哪些私有变量可以通过公共函数访问的对象,比如'var accessList = {“x” :true,“y”:true};'然后在'function test2(a)'你可以说'return accessList [a]? eval(a):undefined; - 优点是这不仅提供了可以传递给eval的字符串的安全性,还允许你定义其他真正的私有变量,这些变量不能通过'test2() 。 – nnnnnn 2011-12-25 11:55:30

7

(至少不是没有诉诸eval,每qwertymk的答案)。

y不是x属性(考虑命名此对象的东西比x更好地避免与局部变量x混乱)。 y是一个局部变量,其中x的方法已经形成闭包。

任何x的方法可以访问y,但不应该说this.y,而是通过直接访问y

再次,y是不是你的对象的财产x。它只是创建了x的函数中的局部变量,因此导致x的方法在其上形成闭包。

因此,要test2返回y,只是做:

test2: function(){ 
    return y; 
} 

要创建一个方法可以让你访问私有变量,可以考虑这样的事情:

var x = (function() { 
    var privateMembers = { x: 0, y: 2, z: 5 }; 

    return { 
     getPrivate: function (name) { 
      return privateMembers[name]; 
     }, 
     toast: 123, 
     test1: function (arg) { 
      return this[arg]; 
     }, 
     test2: function() { 
      // ?? 
     } 
    }; 
})(); 

而且那么

alert(x.getPrivate("y")); //alerts 2 

退房this fiddle

+0

你会怎么推荐蒂姆解决缺少代码'TEST2()' ? – mauris 2011-12-25 04:31:37

+0

伟大的答案,但那是我的替代解决方案(创建一个单独的私人对象,以访问我的私有变量在公共职能),我想知道是否有另一种(更美丽)的方式来做到这一点? – 2011-12-25 04:43:37

+0

@Tim--不是我能想到的。就个人而言,我认为上面的方式更美观:) – 2011-12-25 04:45:17

相关问题