Chuyển đổi chuỗi thành tên biến trong JavaScript


260

Tôi đã tìm giải pháp, nhưng không thể tìm thấy bất kỳ công việc nào.

Tôi có một biến được gọi là onlyVideo.

"onlyVideo"chuỗi được truyền vào một hàm. Tôi muốn đặt biến onlyVideobên trong hàm là một cái gì đó. Làm thế nào tôi có thể làm điều đó?

(Có một số biến có thể được gọi vào hàm, vì vậy tôi cần nó để hoạt động linh hoạt, không phải là các ifcâu lệnh được mã hóa cứng .)

Chỉnh sửa: Có lẽ có một cách tốt hơn để làm những gì bạn đang cố gắng làm. Tôi đã hỏi điều này sớm trong cuộc phiêu lưu JavaScript của tôi. Kiểm tra cách các đối tượng JavaScript hoạt động.

Giới thiệu đơn giản:

// create JavaScript object
var obj = { "key1": 1 };

// assign - set "key2" to 2
obj.key2 = 2;

// read values
obj.key1 === 1;
obj.key2 === 2;

// read values with a string, same result as above
// but works with special characters and spaces
// and of course variables
obj["key1"] === 1;
obj["key2"] === 2;

// read with a variable
var key1Str = "key1";
obj[key1Str] === 1;

5
Bạn đang sử dụng cái này để làm gì? Bạn có chắc chắn rằng bạn cần đặt nó thành một biến cục bộ bình thường và Đối tượng (Hash) sẽ không hoạt động?
Dogbert

Mmm ... Tôi vẫn không hiểu tại sao bạn muốn làm điều này trong một thế giới với các mảng. Dù sao, một số mã và giải thích của bạn sẽ giúp rất nhiều.
Kevin Chavez

tôi nghĩ rằng chúng tôi cần chi tiết hơn về mục tiêu cuối cùng của bạn là gì
mcgrailm

Câu trả lời:


280

Nếu đó là một biến toàn cục thì window[variableName] hoặc trong trường hợp của bạn window["onlyVideo"]nên thực hiện thủ thuật.


35
Ngay cả khi không phải là toàn cầu, bạn có thể truy cập nó như thế bằng scope[property]hoặc thậm chíthis[property]
Wojciech Bednarski

7
@WojciechBednarski: Đừng nhầm lẫn phạm vi và bối cảnh. thislà bối cảnh, những gì nó chỉ ra phụ thuộc vào cách gọi hàm. Trong JS, 50% thời gian thiswindowtrừ khi bạn kích hoạt chế độ nghiêm ngặt và thistrở thành undefinedvà sẽ gây ra lỗi. Phạm vi là một cái gì đó hoàn toàn khác và nó không phải là một đối tượng (ngoại trừ phạm vi toàn cầu được nhân đôi bởi windowđối tượng)
slebetman

3
Không hoạt động trong WebWorkers(nơi selfgiới thiệu phạm vi toàn cầu, giống như trong trình duyệt, nơi nó bằng window) và Node.js, đâu globallà biến bạn muốn. Và nó mới hơn hoạt động với phạm vi địa phương, chẳng hạn như cơ thể chức năng.
Tomáš Zato - Phục hồi Monica

Có cách nào để xác định constsử dụng phương pháp này không?
toing_to

165

Javascript có eval()chức năng cho những dịp như vậy:

function (varString) {
  var myVar = eval(varString);
  // .....
}

Chỉnh sửa: Xin lỗi, tôi nghĩ rằng tôi đã lướt qua câu hỏi quá nhanh. Điều này sẽ chỉ giúp bạn có được biến, để đặt nó bạn cần

function SetTo5(varString) {
  var newValue = 5;
  eval(varString + " = " + newValue);
}

hoặc nếu sử dụng một chuỗi:

function SetToString(varString) {
  var newValue = "string";
  eval(varString + " = " + "'" + newValue + "'");
}

Nhưng tôi tưởng tượng có một cách thích hợp hơn để thực hiện những gì bạn đang tìm kiếm? Tôi không nghĩ eval () là thứ bạn thực sự muốn sử dụng trừ khi có lý do tuyệt vời cho nó. đánh giá ()


3
Vâng tôi sẽ đi với cái này hơn là sử dụng cửa sổ (nó có một số cảnh báo)
ingo

12
Tại sao một eval()câu trả lời bị bỏ qua để xóa, và câu trả lời này bị bỏ qua?
BoltClock

4
@goggin Bạn nên kiểm tra lại đối số để đảm bảo rằng đó là tên hợp lệ. Chỉ cần trốn tránh tranh luận mà không kiểm tra nó trước là không an toàn.
Vidime Vidas

16
Đây là câu trả lời thực tế duy nhất cho câu hỏi. Chỉ vì nó liên quan đến eval "eeeeevil" không làm cho nó ít đúng hơn. Javascript không có các biến số (như $$ varname trong php) vì vậy đây thực sự là câu trả lời duy nhất. Việc sử dụng window[varname]có tác dụng phụ của việc giới thiệu các biến toàn cục, có thể không muốn. @Shaz Tôi không nghĩ bạn cung cấp cho trình thông dịch JS hiện đại đủ tín dụng. Chúng cực kỳ nhanh, và phân tích cú pháp và thực hiện thao tác gán một dòng đơn giản sẽ không tăng tốc độ sử dụng CPU của bất kỳ ai, miễn là nó không được thực hiện trong bộ đếm thời gian 1ms hoặc vòng lặp chặt chẽ.
MooGoo

2
@TheParamag từCroissant Những người đam mê chăm sóc mã. Những người chỉ coi trọng thời gian và tiền bạc thì không.
Jimbo

41

Theo như giải pháp biến đổi so với toàn cầu ...

Tôi nghĩ rằng có những lợi thế cho mỗi nhưng đây thực sự là một sự phân đôi giả. Nếu bạn hoang tưởng về không gian tên toàn cầu, chỉ cần tạo một không gian tên tạm thời & sử dụng cùng một kỹ thuật.

var tempNamespace = {};
var myString = "myVarProperty";

tempNamespace[myString] = 5;

Khá chắc chắn rằng sau đó bạn có thể truy cập dưới dạng tempNamespace.myVarProperty (hiện 5), tránh sử dụng cửa sổ để lưu trữ. (Chuỗi cũng có thể được đặt trực tiếp vào dấu ngoặc)


Một chút cấu trúc lại mã của bạn để tạo cùng một varppamesames = {["myVarProperty"]: "Chắc chắn chỉ có video"};
Tioma

1
Đây là một giải pháp rất tốt - có vẻ như nên tránh eval () trừ khi thực sự cần thiết, cách giải quyết rất thanh lịch ở đây.
skwidbreth

Bắt đầu với bộ sưu tập document.body.getElementsByTagName ('*'), thật dễ dàng tìm thấy tất cả các phần tử có thuộc tính 'id' và tạo một biến cho giá trị đối tượng phần tử của từng đối tượng trong một đối tượng toàn cầu 'id'. Sau đó, bạn có thể tham khảo <div id = container> trong JavaScript dưới dạng 'id.container'. Quá dễ!
David Spector

15
var myString = "echoHello";

window[myString] = function() {
    alert("Hello!");
}

echoHello();

Nói không với tà ác . Ví dụ ở đây: https://jsfiddle.net/Shaz/WmA8t/


3
Làm cho công việc này trên phạm vi địa phương và tôi sẽ loại bỏ downvote.
Tomáš Zato - Phục hồi Monica

@ TomášZatofunction aScope() { this[myString] = function() { alert("Hello!"); };};
rrw

@richmondwang thiskhông giới thiệu phạm vi cục bộ mà là đối tượng mà hàm bị ràng buộc trong khi gọi.
Tomáš Zato - Phục hồi Monica

8

Bạn có thể truy cập đối tượng cửa sổ dưới dạng một mảng kết hợp và đặt nó theo cách đó

window["onlyVideo"] = "TEST";
document.write(onlyVideo);

8

Phương thức CHỈ cửa sổ ['biếnName'] hoạt động nếu biến được xác định trong phạm vi toàn cục. Câu trả lời đúng là "Refactor". Nếu bạn có thể cung cấp một bối cảnh "Đối tượng" thì một giải pháp chung có thể tồn tại, nhưng có một số biến mà không có hàm toàn cầu nào có thể giải quyết dựa trên phạm vi của biến.

(function(){
    var findMe = 'no way';
})();

6

Nếu bạn đang cố gắng truy cập vào thuộc tính của một đối tượng, bạn phải bắt đầu với phạm vi windowvà đi qua từng thuộc tính của đối tượng cho đến khi bạn đến được đối tượng bạn muốn. Giả sử a.b.cđã được xác định ở một nơi khác trong tập lệnh, bạn có thể sử dụng như sau:

var values = window;
var str = 'a.b.c'.values.split('.');

for(var i=0; i < str.length; i++)
    values = values[str[i]];

Điều này sẽ làm việc để có được tài sản của bất kỳ đối tượng nào, bất kể nó sâu đến đâu.


Ví dụ của bạn là mát mẻ. Tôi lưu ý rằng nếu tôi sử dụng namelàm tên biến, ví dụ của bạn không thành công, nhưng nó hoạt động với các tên biến khác. Điều này có thể phải làm với đối tượng Window đã có một namebiến. Ngoài ra, bao gồm cả .valuephương pháp gây ra thất bại. Khả năng diễn giải các biến đối tượng lồng nhau sâu sắc là những gì tôi đang tìm kiếm và phương pháp của bạn chỉ ra một hướng tốt. Cảm ơn.
Theo

Không vấn đề gì. Câu trả lời là để chứng minh khái niệm hơn là câu trả lời sao chép / dán (như hầu hết các câu trả lời ở đây trên SO tôi nghĩ)

1
Phản hồi SO thậm chí còn tốt hơn khi bạn có thể dành thời gian cải thiện chúng thay vì sửa chúng. ;-)
Theo

Không hoạt động:Uncaught TypeError: Cannot read property 'split' of undefined
Roberto14


0

Nó có thể được thực hiện như thế này

(function(X, Y) {
  
  // X is the local name of the 'class'
  // Doo is default value if param X is empty
  var X = (typeof X == 'string') ? X: 'Doo';
  var Y = (typeof Y == 'string') ? Y: 'doo';
  
  // this refers to the local X defined above
  this[X] = function(doo) {
    // object variable
    this.doo = doo || 'doo it';
  }
  // prototypal inheritance for methods
  // defined by another
  this[X].prototype[Y] = function() {
    return this.doo || 'doo';
  };
  
  // make X global
  window[X] = this[X];
}('Dooa', 'dooa')); // give the names here

// test
doo = new Dooa('abc');
doo2 = new Dooa('def');
console.log(doo.dooa());
console.log(doo2.dooa());


0

Đoạn mã sau giúp bạn dễ dàng tham khảo từng DIV và các thành phần HTML khác trong JavaScript. Mã này phải được đưa vào ngay trước thẻ, để tất cả các yếu tố HTML đã được nhìn thấy. Nó phải được theo sau bởi mã JavaScript của bạn.

// For each element with an id (example: 'MyDIV') in the body, create a variable
// for easy reference. An example is below.
var D=document;
var id={}; // All ID elements
var els=document.body.getElementsByTagName('*');
for (var i = 0; i < els.length; i++)
    {
    thisid = els[i].id;
    if (!thisid)
        continue;
    val=D.getElementById(thisid);
    id[thisid]=val;
    }

// Usage:
id.MyDIV.innerHTML="hello";
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.