我想使用变量的值来访问一个对象。
假设我有一个名为myobject的对象。
我想用这个名称填充一个变量,并使用该变量访问该对象。
示例:
var objname = 'myobject';
{objname}.value = 'value';
var objname = 'myobject';
{objname}.value = 'value';
全局变量:
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({});
在变量名周围使用方括号。
var objname = 'myobject';
{[objname]}.value = 'value';
这是一个全局变量吗?如果是,它们实际上是 window
对象的一部分,因此您可以使用 window[objname].value
.
如果它是函数内的局部变量,我认为没有好的方法可以做到你想要的。
对象存在于某个作用域中,因此您几乎可以始终通过以下语法访问变量:
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]
})();
eval
函数:eval(variablename + ".value = 'value'");
eval
可以执行的JS代码。 - Midaseval
的少数合法用途之一。但我们必须确保变量是干净的。 - Levi MorrisonmyVar[objname].value
的操作? - JW.一般情况下无法这样做,除非在窗口范围内,您可以编写 window[objname].value = 'value';
我认为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);
})();
这基本上与创建一个全局变量来存储变量并将其作为属性访问是相同的。创建全局变量是一种hack方法。
以下是一种更干净的hack方法,它不会创建全局变量,而是使用本地变量。
function doIt() {
var scope = {
MyProp: "Hello"
};
var name = "MyProp";
console.log(scope[name]);
}
方括号可以用来使键变得动态,就像这样
var myObjKey = "key";
var obj = {[myObjKey] : "value" };
console.log(obj); // => {key: 'value'}
var anotherObj = {["justString"] : "value" };
console.log(anotherObj ); // => {justString: 'value'}
let players = [];
players[something] = {};
players[something].somethingElse = 'test';
console.log(players);
-> [ something: { somethingElse: 'test' } ];
Company.Module.Components.Foo
,则可以使用此函数: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
window
对象上设置了一个名为objname
的变量,然后通过this
引用它...你可以在第二个示例中将window
替换为this
,一切仍将正常工作。 :-) - Sean Vieiraarguments.callee
已经被弃用,但它仍然是一个非常聪明的实现方式--而且它不会污染全局作用域。+1 - Sean Vieiraobjname
保持为函数本身的属性。这可能会在递归函数中失败。不确定这在现实世界中如何使用。 - Ruan Mendesarguments.callee
。 - Shaz