2009-02-28 6 views
18

動的にあなたが使用することができます。javascriptでローカルスコープに動的にアクセスするにはどうしたらいいですか?あなたはグローバル関数と変数を使用したい場合は

window[functionName](window[varName]); 

それはローカルスコープ内の変数に同じことを行うことは可能ですか?

このコードは正しく動作しますが、現在はevalを使用していますが、他にどのように行うかを考えようとしています。

var test = function(){ 
    //this = window 
    var a, b, c; //private variables 

    var prop = function(name, def){ 
     //this = window 
     eval(name+ ' = ' + (def.toSource() || undefined) + ';');  

     return function(value){ 
      //this = test object 
      if (!value) { 
       return eval('(' + name + ')'); 
      } 
      eval(name + ' = value;') 
      return this; 
     }; 

    }; 

    return { 
     a:prop('a', 1), 
     b:prop('b', 2), 
     c:prop('c', 3), 
     d:function(){ 
      //to show that they are accessible via to methods 
      return [a,b,c]; 
     } 
    }; 
}(); 

>>>test 
Object 
>>>test.prop 
undefined 
>>>test.a 
function() 
>>>test.a() 
1 //returns the default 
>>>test.a(123) 
Object //returns the object 
>>>test.a() 
123 //returns the changed private variable 
>>>test.d() 
[123,2,3] 
+1

なぜ私は今混乱していたのですか。なぜなら、変数abc AS WELLは戻り値の名前になっているからです。あなたはそれらの名前を変更する必要があります、それは私を混乱させるものでした。とにかく、私のものよりも良い答えが現れました。だから、私はこの時点でcrescentfreshにゆだねるつもりです。 –

+0

@ゴートあなたがリンクしている質問は、何か違うことを求めています。彼がアクセスしようとしている変数はグローバル変数です。受け入れられた答えはグローバル変数も使用します。リンクされた質問は変更する必要があります。 – Annan

答えて

6

いいえ、crescentfreshといいます。以下は、evalなしで実装する方法の例ですが、内部のプライベートオブジェクトを使用しています。

var test = function() { 
    var prv={ }; 
    function prop(name, def) { 
    prv[name] = def; 
    return function(value) { 
     // if (!value) is true for 'undefined', 'null', '0', NaN, '' (empty string) and false. 
     // I assume you wanted undefined. If you also want null add: || value===null 
     // Another way is to check arguments.length to get how many parameters was 
     // given to this function when it was called. 
     if (typeof value === "undefined"){ 
     //check if hasOwnProperty so you don't unexpected results from 
     //the objects prototype. 
     return Object.prototype.hasOwnProperty.call(prv,name) ? prv[name] : undefined; 
     } 
     prv[name]=value; 
     return this; 
    } 
    }; 

    return pub = { 
    a:prop('a', 1), 
    b:prop('b', 2), 
    c:prop('c', 3), 
    d:function(){ 
     //to show that they are accessible via two methods 
     //This is a case where 'with' could be used since it only reads from the object. 
     return [prv.a,prv.b,prv.c]; 
    } 
    }; 
}(); 
+0

関数自体のローカル変数を列挙するとどうなりますか?言い換えれば、評価のようなものですが、地元の人々が何であるかわからないときは... – Michael

+0

@Michael申し訳ありませんが、私はあなたが意味することを理解していません。例を挙げていただけますか?または、あなた自身の答えを書くかもしれませんか? – some

+0

私は答えがなく、私が読んだことはすべて不可能であると思われます。ブラウザのグローバル変数は 'for(i in window)'のようなもので列挙できます。もしそれが関数内の地元の人にとって可能だったらいいでしょう。 – Michael

2

うまくいけば、私は過度に簡素化しているのではないでしょうか?

var test = { 
    getValue : function(localName){ 
     return this[localName]; 
    }, 
    setValue : function(localName, value){ 
     return this[localName] = value; 
    } 
}; 

>>> test.a = 123 
>>> test.getValue('a') 
123 
>>> test.a 
123 

>>> test.setValue('b', 999) 
999 
>>> test.b 
999 
+0

オブジェクトのローカル変数に直接アクセスする場合は、getterまたはsetterを定義するという点は何ですか? –

+0

ありません。私はちょうどそれを使用してアナンの例と同じであることを追加しました。私は同意する、それは実際には完全にばかげているだろう。 –

+0

コードの理由は、ゲッターとセッターがクロスブラウザーでどのように動作するかをエミュレートするためです。したがって、作成された変数prop()がオブジェクトの残りの部分で利用できないため、私の元のコードは間違っていました(現在は修正されています)。あなたの方法は、プロパティの直接アクセスと操作を可能にします。 – Annan

7

あなたの質問に答えるために、いや、eval()を使用せずにローカルスコープに動的変数のルックアップを行うための方法はありません。

「スコープ」を普通のオブジェクト(つまり、"{}")にしてそこにデータを貼り付けるのが最良の方法です。