JavaScriptはオブジェクト名として変数を使用します


89

変数の値を使用してオブジェクトにアクセスしたい。

myobjectという名前のオブジェクトがあるとします。

この名前を変数に入力し、その変数を使用してオブジェクトにアクセスしたいと思います。

例:

var objname = 'myobject';
{objname}.value = 'value';

回答:


123

グローバル:

myObject = { value: 0 };
anObjectName = "myObject";
this[anObjectName].value++;

console.log(this[anObjectName]);

グローバル:v2

var anObjectName = "myObject";
this[anObjectName] = "myvalue"

console.log(myObject)

ローカル:v1

(function() {
    var scope = this;

    if (scope != arguments.callee) {
        arguments.callee.call(arguments.callee);
        return false;
    }

    scope.myObject = { value: 0 };
    scope.anObjectName = "myObject";
    scope[scope.anObjectName].value++;

    console.log(scope.myObject.value);
})();

ローカル:v2

(function() {  
    var scope = this;

    scope.myObject = { value: 0 };
    scope.anObjectName = "myObject";
    scope[scope.anObjectName].value++;

    console.log(scope.myObject.value);    
}).call({});

@Shaz -実際には、これらの基準の両方が同じ範囲;-)(これらは、ブラウザで実行されると仮定) alert(this === window)
Sean Vieira、

1
@PeeHaa - ローカルの例では、上の変数セットwindowと呼ばれるオブジェクトobjname、その後を介して参照されthisますが、置き換えることができ... windowのためのthis第二の例では、すべてがまだ動作しますが。:-)
Sean Vieira、

1
@SeanVieira:更新された例を見てください。うまくいけば、これは現在正しく動作します。
Shaz、

1
@Shaz -はarguments.callee廃止されましたが、それはだ非常にそれにもかかわらず、巧妙な実装- 、それはゴミグローバルスコープをしません。+1
ショーンビエイラ

1
グローバルスコープを汚染しているわけではありませんが、関数のすべての呼び出しで共有されるオブジェクトを作成しています。関数はobjname、関数自体のプロパティとして保持しています。再帰的な関数では失敗する可能性があります。これが実際の世界でどのように使用できるかはわかりません。
ファンメンデス

25

変数名を角括弧で囲みます。

var objname = 'myobject';
{[objname]}.value = 'value';

6
これは完璧でシンプルで、トップの答えになるはずです。
Brad

4
これは例外をスローします:SyntaxError:予期された式、「。」を取得しました。それは動作しません; なぜそれほど多くの賛成票があるのですか?
Lovro、

8

グローバル変数ですか?もしそうなら、これらは実際にはwindowオブジェクトの一部なので、行うことができますwindow[objname].value

それが関数に対してローカルである場合、私はあなたが望むことをする良い方法はないと思います。


7

オブジェクトはあるスコープ内に存在するため、ほとんどの場合、次の構文で変数にアクセスできます。

var objname = "myobject";
containing_scope_reference[objname].some_property = 'some value';

これがトリッキーになる唯一の場所は、閉じたスコープ内にいて、最上位のローカル変数にアクセスしたい場合です。あなたがこのようなものを持っているとき:

(function(){
    var some_variable = {value: 25};
    var x = "some_variable";
    console.log(this[x], window[x]); // Doesn't work
})();

あなたはできる使用していることを周りを取得eval、現在のスコープチェーンにアクセスするために代わりに...しかし、あなたは多くのテストを行ってきたし、あなたがない限り、私はそれをお勧めしません知っていることは、物事を行くための最善の方法だということ。

(function(){
    var some_variable = {value: 25};
    var x = "some_variable";
    eval(x).value = 42;
    console.log(some_variable); // Works
})();

あなたの最善の策は、(thisグローバルスコープやローカルスコープのプライベートトップレベル変数などの)常に存在するオブジェクトの名前への参照を持ち、そこに他のすべてを置くことです。

したがって:

var my_outer_variable = {};
var outer_pointer = 'my_outer_variable';
// Reach my_outer_variable with this[outer_pointer]
// or window[outer_pointer]

(function(){
    var my_inner_scope = {'my_inner_variable': {} };
    var inner_pointer = 'my_inner_variable';
    // Reach my_inner_variable by using
    // my_inner_scope[inner_pointer]
})();

6

あなたが使うことができますeval

eval(variablename + ".value = 'value'");

eval考慮されていませんevilか?そうでなければ私はそれを使うかもしれません。現在はグローバルですが、クリーンアップする関数に移動したかったので。
PeeHaa

1
笑。変数名がユーザー入力に由来する場合は、必ず検証して、eval実行可能なJSコードが含まれないようにしてください。
ミダス、

1
これはeval、私の意見では、の数少ない正当な使用法の1つです。ただし、変数がクリーンであることを確認する必要があります。
Levi Morrison、

2
はい、それは本当に問題ではありません。しかし、シャズからの答えを見てください。私はそれがよりクリーンなソリューションだと思います。
ミダス

2
@PeeHaa:移動を検討している場合は、既知のオブジェクトのプロパティに移動して、次のようなことができるようにしてmyVar[objname].valueください。
JW。

5

あなたが書くことができるウィンドウスコープを除いて、これを一般的に行うことはできません window[objname].value = 'value';


3

ローカル変数に対するShazの答えは理解しにくいと思いますが、非再帰関数では機能します。これは私がより明確だと思う別の方法です(しかし、それは彼のアイデアであり、まったく同じ動作です)。また、ローカル変数に動的にアクセスするのではなく、ローカル変数のプロパティにアクセスします。

基本的に、それはグローバル関数を使用しています(関数オブジェクトにアタッチされています)

// Here's  a version of it that is more straight forward.
function doIt() {
    doIt.objname = {};
    var someObject = "objname";
    doIt[someObject].value = "value";    
    console.log(doIt.objname);
})();

これは、変数を格納するグローバルを作成することと基本的に同じなので、プロパティとしてアクセスできます。これを行うためのグローバルを作成することは、このようなハックです。

これは、グローバル変数を作成しないよりクリーンなハックです。代わりにローカル変数を使用します。

function doIt() {
  var scope = {
     MyProp: "Hello"
  };
  var name = "MyProp";
  console.log(scope[name]);
}

JavaScript:文字列をオブジェクト参照として解釈する」を参照してください


0

window [objname]を使用する場合は、objnameがグローバル変数であることを確認してください。そうでなければ、いつかは動作し、時々失敗します。window [objname] .value。


0

オブジェクトが名前空間にある場合、つまり Company.Module.Components.Fooこの関数を使用できます:

CoffeeScript:

objByName: (name, context = window) ->
    ns = name.split "."
    func = context
    for n, i in ns
        func = func[n]
    return func

結果のJs:

objByName: function(name, context) {
  var func, i, n, ns, _i, _len;
  if (context == null) {
    context = window;
  }
  ns = name.split(".");
  func = context;
  for (i = _i = 0, _len = ns.length; _i < _len; i = ++_i) {
    n = ns[i];
    func = func[n];
  }
  return func;
}

次に、新しいオブジェクトを作成するか、何でもできます。括弧が通っていることに注意してください。

var o = new (objByName('Company.Module.Components.Foo'))
objByName('some.deeply.nested.object').value

このアイデアは、同様の質問から借用したものです:名前を文字列として持っているときにJavaScript関数を実行する方法


0

答えで私が直面した課題の1つは、オブジェクトが単一レベルであると想定したことです。例えば、

const testObj = { testKey: 'testValue' }
const refString = 'testKey';
const refObj = testObj[refString];

正常に動作しますが、

const testObj = { testKey:
                  { level2Key: 'level2Value' }
                }
const refString = 'testKey.level2Key';
const refObj = testObj[refString];

動作しません。

私がやったことは、マルチレベルのオブジェクトにアクセスするための関数を作成することでした:

objVar(str) {
    let obj = this;
    const parts = str.split('.');
    for (let p of parts) {
        obj = obj[p];
    }
    return obj;
}

2番目のシナリオでは、この関数に文字列を渡して、探しているオブジェクトを取得できます。

const testObj = { testKey:
                  { level2Key: 'level2Value' }
                }
const refString = 'testObj.testKey.level2Key';
const refObj = objVar[refString];

0

この方法でオブジェクトのプロパティを設定できます:

var obj = {};
obj.whateverVarName = 'yourVal';
console.log(obj);


0

考えられる変数名のリストがすでにわかっている場合は、プロパティ名がオブジェクト名と同じである新しいObject(iconObj)を作成してみてください。以下の例では、iconLib変数は 'ZondIcons'または 'MaterialIcons'の2つの文字列値を保持します。propertyNameは、ZondIconsまたはMaterialsIconオブジェクトのプロパティです。

   const iconObj = {
    ZondIcons,
    MaterialIcons,
  }
  const objValue = iconObj[iconLib][propertyName]

0
let players = [];
players[something] = {};
players[something].somethingElse = 'test';
console.log(players); 

-> [something:{somethingElse: 'test'}];


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