2011-12-25 1 views
11

Есть ли способ публичной функции из модуля-шаблона, который динамически обрабатывает частные переменные? test1 показывает, что я имею в виду с «доступом динамически», но с публичными переменнымиВозможно ли доступ к частным переменным в шаблоне модуля динамически?

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

Да.

Извините разочаровать Adam 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 должны быть использованы.

EDIT, согласно Hans B 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

+0

@ HansBPUFAL: Отличная идея! Я обязательно добавлю его – qwertymk

+1

+1, но могу ли я предложить альтернативную идею проверки: если вы определяете объект, который указывает, к какой из частных переменных можно получить доступ через публичную функцию, например, 'var accessList = {" x " : true, "y": true}; 'then in' function test2 (a) 'вы можете сказать' return accessList [a]? eval (a): undefined; 'преимущество заключается в том, что это не только обеспечивает безопасность в отношении того, какие строки могут быть переданы в eval, но и позволяет определить другие действительно частные переменные, к которым невозможно получить доступ через' test2() ' , – nnnnnn

7

No (по крайней мере, не прибегая к eval, за ответ qwertymk).

y не является собственностью x (считают называя этот объект что-то лучше, чем x, чтобы избежать путаницы с локальной переменной x). y - локальная переменная, по которой методы x сформировали замыкание.

Любой из методов x «s может получить доступ к 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

+0

отличный ответ, но это было мое альтернативное решение (создание отдельного частного объекта для доступа к моим частным переменным в публичной функции), мне было интересно, есть ли другой (более красивый) способ сделать это? –

+0

@ Тим - не то, о чем я могу думать. Лично я думаю, что выше путь более красив :) –

 Смежные вопросы

  • Нет связанных вопросов^_^