我想使用变量的值来访问对象。
假设我有一个名为myobject的对象。
我想用此名称填充变量,然后使用该变量访问对象。
例:
var objname = 'myobject';
{objname}.value = 'value';
Answers:
全球:
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({});
window调用的对象objname,然后通过参考this...你可以代替window为this在第二个例子中,一切都仍然坚持工作。:-)
arguments.callee已过时,但它是一个非常聪明的实现-并且不会乱扔全局范围。+1
objname函数本身的属性。对于递归函数,它可能会失败。不确定如何在现实世界中使用它。
对象存在于某个范围内,因此您几乎总是可以通过以下语法访问变量:
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考虑evil吗?如果没有,我可能会使用它。因为它现在是全球性的,但我想将其移至一个用于清理内容的函数中。
eval可执行的JS代码。
eval我认为,这是的少数合法使用之一。不过,我们必须确保变量是干净的。
myVar[objname].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);
})();
这与创建用于存储变量的全局变量基本相同,因此您可以将其作为属性来访问。创建一个全局的来做到这一点就是这样的黑客。
这是一个更干净的技巧,它不会创建全局变量,而是使用局部变量。
function doIt() {
var scope = {
MyProp: "Hello"
};
var name = "MyProp";
console.log(scope[name]);
}
如果对象在某个名称空间中,即。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函数
我在回答中遇到的挑战之一是,它假设对象是单个级别。例如,
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;
}
然后,在第二种情况下,我可以将字符串传递给此函数以找回我要查找的对象:
const testObj = { testKey:
{ level2Key: 'level2Value' }
}
const refString = 'testObj.testKey.level2Key';
const refObj = objVar[refString];
alert(this === window)。