Tôi muốn sử dụng giá trị của một biến để truy cập một đối tượng.
Giả sử tôi có một đối tượng tên là myobject.
Tôi muốn điền vào một biến với tên này và sử dụng biến để truy cập đối tượng.
Thí dụ:
var objname = 'myobject';
{objname}.value = 'value';
Câu trả lời:
Toàn cầu:
myObject = { value: 0 };
anObjectName = "myObject";
this[anObjectName].value++;
console.log(this[anObjectName]);
Toàn cầu: v2
var anObjectName = "myObject";
this[anObjectName] = "myvalue"
console.log(myObject)
Địa phương: 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);
})();
Địa phương: v2
(function() {
var scope = this;
scope.myObject = { value: 0 };
scope.anObjectName = "myObject";
scope[scope.anObjectName].value++;
console.log(scope.myObject.value);
}).call({});
windowđối tượng được gọi objname, sau đó được tham chiếu qua this... bạn có thể thay thế windowcho thistrong ví dụ thứ hai và mọi thứ vẫn hoạt động. :-)
arguments.calleekhông được dùng nữa, nhưng dù sao thì đây cũng là một cách triển khai rất thông minh - và nó không làm ảnh hưởng đến phạm vi toàn cầu. +1
objnamenhư một thuộc tính của chính hàm. Nó có thể bị lỗi đối với các hàm đệ quy. Không chắc làm thế nào điều này có thể được sử dụng trong thế giới thực.
Sử dụng dấu ngoặc vuông xung quanh tên biến.
var objname = 'myobject';
{[objname]}.value = 'value';
Đối tượng tồn tại trong một số phạm vi, vì vậy bạn hầu như luôn có thể truy cập biến thông qua cú pháp sau:
var objname = "myobject";
containing_scope_reference[objname].some_property = 'some value';
Nơi duy nhất mà điều này trở nên phức tạp là khi bạn ở trong một phạm vi đóng và bạn muốn truy cập vào một biến cục bộ cấp cao nhất. Khi bạn có một cái gì đó như thế này:
(function(){
var some_variable = {value: 25};
var x = "some_variable";
console.log(this[x], window[x]); // Doesn't work
})();
Thay vào đó, bạn có thể giải quyết vấn đề đó bằng cách sử dụng evalđể truy cập chuỗi phạm vi hiện tại ... nhưng tôi không khuyên bạn nên sử dụng nó trừ khi bạn đã thực hiện nhiều thử nghiệm và bạn biết rằng đó là cách tốt nhất để tiếp tục mọi thứ.
(function(){
var some_variable = {value: 25};
var x = "some_variable";
eval(x).value = 42;
console.log(some_variable); // Works
})();
Đặt cược tốt nhất của bạn là có một tham chiếu đến tên trong một đối tượng luôn-sẽ-tồn-tại (như thistrong phạm vi toàn cục hoặc một biến cấp cao nhất riêng trong phạm vi cục bộ) và đặt mọi thứ khác vào đó.
Như vậy:
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]
})();
Bạn có thể sử dụng eval:
eval(variablename + ".value = 'value'");
evalcoi là evil? Nếu không, tôi có thể sử dụng nó. Bởi vì nó là toàn cầu ngay bây giờ nhưng tôi muốn chuyển nó thành một chức năng để dọn dẹp mọi thứ.
evalcó thể thực thi.
eval, theo ý kiến của tôi. Tuy nhiên, chúng ta phải đảm bảo rằng biến sạch.
myVar[objname].valuenào?
Tôi nghĩ rằng câu trả lời của Shaz cho các biến cục bộ là khó hiểu, mặc dù nó hoạt động cho các hàm không đệ quy. Đây là một cách khác mà tôi nghĩ nó rõ ràng hơn (nhưng đó vẫn là ý tưởng của anh ấy, hành vi giống hệt nhau). Nó cũng không truy cập động các biến cục bộ, chỉ là thuộc tính của biến cục bộ.
Về cơ bản, nó sử dụng một biến toàn cục (được đính kèm với đối tượng hàm)
// 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);
})();
Về cơ bản, điều này giống với việc tạo toàn cục để lưu trữ biến, vì vậy bạn có thể truy cập nó như một thuộc tính. Tạo ra một toàn cầu để làm điều này là một hack.
Đây là một thủ thuật gọn gàng hơn không tạo biến toàn cục, thay vào đó nó sử dụng biến cục bộ.
function doIt() {
var scope = {
MyProp: "Hello"
};
var name = "MyProp";
console.log(scope[name]);
}
Xem Javascript: diễn giải chuỗi dưới dạng tham chiếu đối tượng?
Nếu đối tượng nằm trong một số không gian tên tức là. Company.Module.Components.Foobạn có thể sử dụng chức năng này:
CoffeeScript:
objByName: (name, context = window) ->
ns = name.split "."
func = context
for n, i in ns
func = func[n]
return func
Kết quả 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;
}
Sau đó, bạn có thể tạo một đối tượng mới hoặc làm bất cứ điều gì. Lưu ý các dấu ngoặc đơn thông qua.
var o = new (objByName('Company.Module.Components.Foo'))
objByName('some.deeply.nested.object').value
Ý tưởng này được mượn từ câu hỏi tương tự: Làm thế nào để thực thi một hàm JavaScript khi tôi có tên của nó là một chuỗi
Một trong những thách thức mà tôi gặp phải với câu trả lời là nó giả định rằng đối tượng là một cấp duy nhất. Ví dụ,
const testObj = { testKey: 'testValue' }
const refString = 'testKey';
const refObj = testObj[refString];
hoạt động tốt, nhưng
const testObj = { testKey:
{ level2Key: 'level2Value' }
}
const refString = 'testKey.level2Key';
const refObj = testObj[refString];
không hoạt động.
Cuối cùng, những gì tôi đã làm là xây dựng một chức năng để truy cập các đối tượng đa cấp:
objVar(str) {
let obj = this;
const parts = str.split('.');
for (let p of parts) {
obj = obj[p];
}
return obj;
}
Sau đó, trong tình huống thứ hai, tôi có thể truyền chuỗi vào hàm này để lấy lại đối tượng mà tôi đang tìm kiếm:
const testObj = { testKey:
{ level2Key: 'level2Value' }
}
const refString = 'testObj.testKey.level2Key';
const refObj = objVar[refString];
Bạn có thể đặt thuộc tính đối tượng theo cách này:
var obj = {};
obj.whateverVarName = 'yourVal';
console.log(obj);
Nếu bạn đã biết danh sách các tên biến thể có thể có thì hãy thử tạo một Đối tượng mới (iconObj) có tên thuộc tính giống với tên đối tượng, Ở đây trong ví dụ dưới đây, biến iconLib sẽ chứa hai giá trị chuỗi, 'ZondIcons' hoặc 'MaterialIcons' . propertyName là thuộc tính của ZondIcons hoặc đối tượng MaterialsIcon.
const iconObj = {
ZondIcons,
MaterialIcons,
}
const objValue = iconObj[iconLib][propertyName]
var micro=[{'test':'hello'}];
var device = 'test';
console.log(micro[device]);
alert(this === window).