2011-05-21 54 views
72

我想使用变量的值来访问对象。Javascript使用变量作为对象名称

比方说,我有一个名为myobject的对象。

我想用这个名称填充一个变量并使用该变量来访问该对象。

例子:

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

回答

100

全球:

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

console.log(this[anObjectName]); 

全球:V2

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

console.log(myObject) 

Local: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({}); 
+0

@Shaz:哈!如何聪明... – PeeHaa 2011-05-21 22:47:54

+0

@Shaz - 这两个引用实际上相同的范围;-)(假设它们在浏览器中执行)'alert(this === window)''。 – 2011-05-21 22:48:32

+0

@肖恩:他们是。他们呢? – PeeHaa 2011-05-21 22:49:33

6

它是一个全局变量?如果是这样,这些实际上是window对象的一部分,因此您可以执行window[objname].value

如果它是本地的功能,我不认为有一个很好的方法来做你想要的。

5

你不能做到这一点一般,除了在窗口范围,在那里你可以写window[objname].value = 'value';

5

你可以使用eval

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

是不是'eval'被认为是'邪恶的'?如果没有,我可能会使用它。因为它现在是全球性的,但我想把它变成一个清理东西的函数。 – PeeHaa 2011-05-21 22:38:01

+1

哈哈。如果变量名来自用户输入,请确保验证它,以便它不包含任何'eval'可执行的JS代码。 – Midas 2011-05-21 22:42:11

+0

@Midas:它不是直接来自用户输入。但是来自HTML元素的数据内容。用户当然可以操作。但是,如果用户可以执行他自己的JS代码,我不会看到有什么不好。它只会在客户端执行或者我错过了什么? – PeeHaa 2011-05-21 22:46:19

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] 
})(); 
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: interpret string as object reference?

0

当使用窗口[objname表],请确保objname是全局变量。否则,有时会工作,有时会失败。 窗口[objname] .value。

0

如果对象位于某些名称空间中,也就是说。​​您可以使用此功能:

的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 

这个想法是从类似的问题,借:How to execute a JavaScript function when I have its name as a string

-1
var micro=[{'test':'hello'}]; 

var device = 'test'; 

console.log(micro[device]); 
3

各地的变量名称用方括号。

var objname = 'myobject'; 
{[objname]}.value = 'value'; 
相关问题