JavaScriptで動的変数名を使用する


344

PHPでは、次のような驚くべき/恐ろしいことを行うことができます。

$a = 1;
$b = 2;
$c = 3;
$name = 'a';
echo $$name;
// prints 1

JavaScriptでこのようなことをする方法はありますか?

たとえば、私が持っvar name = 'the name of the variable';ている場合、名前を持つ変数への参照を取得できnameますか?


2
stackoverflow.com/questions/724857/…stackoverflow.com/questions/1664282/…の重複の可能性がありますが、ここで認められている答えはIMOです。
goodeye 2013年

これはあなたの質問に答えますか?JavaScriptの「変数」変数?。そこに受け入れられた答えは、それを行う方法を示しているため、ここの答えよりも優れていますが、ほとんど常に、やりたいことを行うためのより良い方法があることを正しく警告しています。メタのXY問題を参照してください。
ggorlen

回答:


353

ECMA- / Javascriptがすべてに約あるのでObjects及びContexts(somekindオブジェクトのもである、)、すべての変数が呼び出さように格納されVariable-(または機能の場合には、アクティベーションオブジェクト)。

したがって、次のような変数を作成するとします。

var a = 1,
    b = 2,
    c = 3;

では、グローバルスコープ(= NOの関数コンテキスト)は、暗黙的にこれらの変数を書くグローバルオブジェクト(= windowブラウザで)。

これらは、「ドット」または「ブラケット」表記を使用してアクセスできます。

var name = window.a;

または

var name = window['a'];

これは、この特定のインスタンスではグローバルオブジェクトのために働く変数オブジェクトグローバルオブジェクトがあるwindowオブジェクトそのもの。関数のコンテキスト内では、アクティベーションオブジェクトに直接アクセスすることはできません。例えば:

function foobar() {
   this.a = 1;
   this.b = 2;

   var name = window['a']; // === undefined
   alert(name);
   name = this['a']; // === 1
   alert(name);
}

new foobar();

new自己定義オブジェクト(コンテキスト)の新しいインスタンスを作成します。new関数のスコープがない場合もglobal(= window)になります。この例ではundefined1それぞれ警告します。置き換える場合this.a = 1; this.b = 2

var a = 1,
    b = 2;

両方のアラート出力は未定義になります。そのシナリオでは、変数aとすることbから、アクティベーションオブジェクトに格納されているになるだろうfoobar(もちろん、我々は呼び出すことで直接それらにアクセスすることができた我々はアクセスできない、ab)。


1
もう1つのすばらしい点は、この方法でグローバルレベルの関数にコールバック(開始/終了)を追加できることです。
2012

5
しかし、動的変数が関数内でローカルである場合はどうなりますか?例:function boink(){var a = 1; //これは機能しませんvar dynamic = this ['a']; //これも機能しませんvar dynamic = ['a']; }
ココドコ2013年

@Kokodoko — これは「コンテキスト」または関数の実行コンテキストへの参照ではないため(実行コンテキストを参照する方法はないため、ECMA-262では禁止されています)。これは、関数の呼び出し方法(またはbind)によって設定されます。これは、アクセス可能な実行コンテキストとは何の関係もない単なるオブジェクトです。
RobG

ネストされたプロパティにアクセスする必要がある場合は、stackoverflow.com / questions / 4244896
Mr Br

ブラケット表記で私を正しい方向に向けました。ドット表記のみ考えてこだわっていました。
Andrew

149

eval 1つのオプションです。

var a = 1;
var name = 'a';

document.write(eval(name)); // 1

19
いいえ、それはevalが悪であるはずがないからです。evalを使用しないでください!
EasyBB、2014年

52
@EasyBB-あなたが何かを決して使用しないと言うつもりなら、私はその理由を説明するのに役立ちません。私はeval()以外に自分がやっていることを達成する他の方法を考えることができない状況にあります
Rampant Creative Group

4
Evalはエンドユーザーへの攻撃のリスクをもたらすため、技術的に悪ではなく、紛失した場合に誤解され、誤用されることはありません。私はリテラル変数を保持するphp応答を見た後、evalを使用してそれを実行します。より良い方法があるのでこれはこの場合使用されるべきではありませんが。全体的にはより良い方法があり、私たちの多くがこれを知っていると確信しているため、この質問evalはまったく使用しないでください。
EasyBB 2014年

2
経由javascriptweblog.wordpress.com/2010/04/19/how-evil-is-eval ---「レッツは、最も頻繁にevalを使用しないように水平に引数を考えてみましょう。それは、コンパイルを必要とする)ので、遅い2である1)何Aの場合悪意のあるスクリプトがeval引数に侵入しましたか?3)醜いように見えます4)実行コンテキストと、呼び出されたスコープのこのバインディングを継承します」
mattLummus

1
:ここではevalを使用して動的変数を作成する方法であるstackoverflow.com/a/13291766/5528600
am2124429

80

ウィンドウオブジェクトを使用して取得できます。

window['myVar']

window 使用しているすべてのグローバル変数とグローバル関数への参照があります。


28
そして言うまでもなく、これはeval()より安全です。
クレイ

45

悪い回答が何票を獲得するのかわからない。答えは簡単ですが、複雑にします。

// If you want to get article_count
// var article_count = 1000;
var type = 'article';
this[type+'_count'] = 1000;  // in a function we use "this";
alert(article_count);

13
「私たちが使用する関数で this」- この方法でグローバル変数にアクセスする場合は、明示的windowでなく、オブジェクトを使用することをお勧めしますthisthisあいまいです。
MrWhite 2015

1
ただし、関数の内部ではthis、やその他の変数を使用して変数にアクセスすることはできません。typeあなたが別の変数にその名前を持っている場合、あなたの例からは:function test(vname) { var type = 'article'; this[vname] = 'something else'; alert(type); }; test('type')表示されますarticle、ではありませんsomething else。そして、それは「複雑な答え」が説明するものです。
オラフ

28
a = 'varname';
str = a+' = '+'123';
eval(str)
alert(varname);

これを試して...


27

これは例です:

for(var i=0; i<=3; i++) {
    window['p'+i] = "hello " + i;
}

alert(p0); // hello 0
alert(p1); // hello 1
alert(p2); // hello 2
alert(p3); // hello 3

もう一つの例 :

var myVariable = 'coco';
window[myVariable] = 'riko';

alert(coco); // display : riko

したがって、myVariableの値「coco」は変数になります cocoに

これは、グローバルスコープのすべての変数がWindowオブジェクトのプロパティだからです。


14

JavaScriptでは、すべてのプロパティがキーと値のペアであるという事実を使用できます。jAndyはすでにこれについて言及しましたが、彼の答えがそれがどのように悪用されるかを示しているとは思いません。

通常は、変数名を保持する変数を作成するのではなく、変数名を生成して使用します。PHPはそれを行います$$var表記ますが、プロパティキーは配列キーと交換可能であるため、Javascriptは必要ありません。

var id = "abc";
var mine = {};
mine[id] = 123;
console.log(mine.abc);

123を返します。通常、変数を構築する必要があるため、間接指定が存在するため、逆の方法でも実行できます。

var mine = {};
mine.abc = 123;
console.log(mine["a"+"bc"]);

1
var someJsonObj = {}; ループ内.... for(var i = 0; i <= 3; i ++){someJsonObj [i] = []; }、しかし私は何でもいいです。動的に生成される変数はすべて、簡単に参照できるようにsomeJsonObj内にあります。
rajeev 2017

5

2019年

TL; DR

  • eval 演算子は、呼び出したコンテキストで文字列式を実行し、そのコンテキストから変数を返すことができます。
  • literal object理論的には、書き込みによってそれを行うことができます{[varName]}

だから私はこの質問に出くわし、ここにいる全員が実際の解決策をもたらすことなく遊んでいます。しかし、@ Axel Heiderは良いアプローチをしています。

解決策はevalです。ほとんど忘れられたオペレーター。(ほとんどの人がそうだと思うwith()

eval演算子は、呼び出したコンテキストで式を動的に実行できます。その式の結果を返します。これを使用して、関数のコンテキストで変数の値を動的に返すことができます。

例:

function exmaple1(){
   var a = 1, b = 2, default = 3;
   var name = 'a';
   return eval(name)
}

example1() // return 1


function example2(option){
  var a = 1, b = 2, defaultValue = 3;

  switch(option){
    case 'a': name = 'a'; break;
    case 'b': name = 'b'; break;
    default: name = 'defaultValue';
  }
  return eval (name);
}

example2('a') // return 1
example2('b') // return 2
example2() // return 3

私は常に明示的に式evalが実行されるように書くことに注意してください。コードの不必要な驚きを避けるため。evalとても強い ですが、あなたはすでにそれを知っていると確信しています

ところで、それが合法である場合literal object、変数の名前と値をキャプチャするために使用できますが、計算されたプロパティ名とプロパティ値を組み合わせることができません。

functopn example( varName ){
    var var1 = 'foo', var2 ='bar'

    var capture = {[varName]}

}

example('var1') //trow 'Uncaught SyntaxError: Unexpected token }`

これは高速なソリューションですが、JSエンジンがそのメソッドを最適化できないため、安全でなくパフォーマンスが低下するため、不適切な方法です。
ディエゴオルティス

素晴らしいソリューション
Rohit Parte

4

ウィンドウやグローバル(ノード)などのグローバルオブジェクトを使用したくない場合は、次のようにしてみてください。

var obj = {};
obj['whatever'] = 'There\'s no need to store even more stuff in a global object.';

console.log(obj['whatever']);

4

複数のFormDataをその場で描画する必要があり、オブジェクトの方法はうまく機能しました

var forms = {}

次に、ループで、使用したフォームデータを作成する必要がある場合はいつでも

forms["formdata"+counter]=new FormData();
forms["formdata"+counter].append(var_name, var_value);

ありがとう...それは私を完全に救った!this。$ refs ['listView' + index] .nativeView.animate({..})私はthis。$ refs.listView1 listView2などの参照内に変数が必要でした...
Meiki Neumann

2

これは、動的に名前が付けられた変数をエクスポートする必要がある人のための代替手段です

export {
  [someVariable]: 'some value',
  [anotherVariable]: 'another value',
}

// then.... import from another file like this:
import * as vars from './some-file'

別の方法は、キーが動的に命名されるオブジェクトを単に作成することです

const vars = { [someVariable]: 1, [otherVariable]: 2 };

// consume it like this
vars[someVariable];

1

彼らが意味することはノーです、あなたはできません。それを成し遂げる方法はありません。だからあなたはこのようなことをすることができました

function create(obj, const){
// where obj is an object and const is a variable name
function const () {}

const.prototype.myProperty = property_value;
// .. more prototype

return new const();

}

ECMAScript 5に実装されているものと同じような作成関数を持っている


4
注意:constはES6のキーワードです
Tejas Manohar

4
...そしてそれ以前は将来の予約語でした。
TJクラウダー

そこにあるevalオペレータ
ペリーのmimonは

1

テストではeval()が機能しませんでした。ただし、DOMツリーに新しいJavaScriptコードを追加することは可能です。だからここに新しい変数を追加する関数があります:

function createVariable(varName,varContent)
{
  var scriptStr = "var "+varName+"= \""+varContent+"\""

  var node_scriptCode = document.createTextNode( scriptStr )
  var node_script = document.createElement("script");
  node_script.type = "text/javascript"
  node_script.appendChild(node_scriptCode);

  var node_head = document.getElementsByTagName("head")[0]
  node_head.appendChild(node_script);
}

createVariable("dynamicVar", "some content")
console.log(dynamicVar)

2
小さな改善var node_head = document.getElementsByTagName("head")[0]です。IDの代わりに使用することをおid="head"<head>
勧めし

私はそうします:)しかし、おかげで、私はようやくこの `id =" head "を削除することができます
Axel Heider

1
これは、グローバル変数を作成するための過度に複雑な方法のようです!?(...そして、これはどのように質問に答えますか?)
MrWhite

genius :) evalが解決策です。コードが機能しない場合でも
pery mimon

1

これには受け入れられた答えがありますが、私は所見を追加したいと思います:

ES6では使用let できません

/*this is NOT working*/
let t = "skyBlue",
    m = "gold",
    b = "tomato";

let color = window["b"];
console.log(color);

しかし作品を使用しvar

/*this IS working*/
var t = "skyBlue",
    m = "gold",
    b = "tomato";

let color = window["b"];
console.log(color);

これが一部に役立つことを願っています。


1
同じことが当てはまりますconst

1
そうだね。ただし、変数を使用してオブジェクトを作成し、そこから変数を選択できますconst vars = { t, m, b }; console.log(vars['b'])。それ以外の場合もeval動作します。
Fabian von Ellerts、

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.