Перетворити рядок у ім'я змінної в JavaScript


260

Я шукав рішення, але не зміг знайти жодної роботи.

У мене є змінна назва onlyVideo.

"onlyVideo"рядок передається у функцію. Я хочу встановити змінну onlyVideoвсередині функції як щось. Як я можу це зробити?

(Існує ряд змінних, які можна викликати у функцію, тому мені потрібно, щоб вона працювала динамічно, а не жорстко кодовані ifзаяви.)

Редагувати: Мабуть, є кращий спосіб робити те, що ви намагаєтеся зробити. Я запитав це рано в моїй пригоді JavaScript. Перевірте, як працюють об’єкти JavaScript.

Просте вступ:

// 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
Для чого ви це використовуєте? Ви абсолютно впевнені, що вам потрібно встановити його на звичайну локальну змінну, і Object (Hash) не працюватиме?
Догберт

ммм ... Я все ще не розумію, чому ти хочеш це робити у світі з масивами. Як би там не було, ваш код та пояснення допоможуть дуже багато.
Кевін Чавес

я думаю, нам потрібна більш детальна інформація про те, яка ваша кінцева мета
mcgrailm

Відповіді:


280

Якщо це глобальна змінна, то window[variableName] або у вашому випадку window["onlyVideo"]слід зробити трюк.


35
Навіть якщо це не глобально, ви можете отримати доступ до нього так scope[property]чи навітьthis[property]
Войцех Беднарський

7
@WojciechBednarski: Не плутайте рамки та контекст. thisце контекст, на що він вказує, залежить від того, як називається функція. У JS 50% часу thisстановить, windowякщо ви не ввімкнете суворий режим і thisне undefinedстанете і не введете помилку. Область застосування - це зовсім інше, і це не об'єкт (за винятком глобальної сфери, яка відображається windowоб'єктом)
slebetman

3
Не працює в WebWorkers(де selfпереходить до глобальної області, як і в браузері, де вона дорівнює window) та Node.js, де globalпотрібна змінна. І новіше працює з локальними областями, такими як функціональний орган.
Томаш Зато - Відновіть Моніку

чи все-таки можна визначити constвикористання цього методу?
toing_toing

165

Javascript має eval()функцію для таких випадків:

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

Редагувати: Вибачте, я думаю, що я занадто швидко пропустив це питання. Це дозволить вам отримати лише цю змінну, щоб встановити її вам потрібно

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

або якщо використовується рядок:

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

Але я думаю, що є більш підходящий спосіб досягти того, що ви шукаєте? Я не думаю, що eval () - це те, що ти насправді хочеш використовувати, якщо немає великої причини для цього. eval ()


3
Так, я б пішов з цим, а не з використанням вікна (у ньому є деякі застереження)
інго

12
Чому одна eval()відповідь була заборонена на видалення, а ця - схвалена?
BoltClock

4
@goggin Ви повинні повторно перевірити аргумент, щоб переконатися, що це дійсне ім'я. Смішно незахищеним є лише тестування аргументу, не перевіривши його спочатку.
Šime Vidas

16
Це єдина реалістична відповідь на питання. Тільки тому, що в ній брав участь "eeeeevil", це не робить його менш правдивим. У Javascript немає змінних змінних (наприклад, $$ varname у php), тому це справді єдина відповідь. Використання window[varname]має побічний ефект від введення глобальних змінних, які можуть бути непотрібними. @Shaz Я не думаю, що ви даєте сучасним перекладачам JS достатньо кредиту. Вони надзвичайно швидкі, і аналіз і виконання простої операції з призначення одного рядка не збирається сприймати чиє-небудь використання процесора до тих пір, поки це не робиться в таймері 1 мс або щільному циклі.
MooGoo

2
@TheParamagneticCroissant Люди, які захоплюються питаннями коду. Ті, хто цінує лише час і гроші, цього не роблять.
Джимбо

41

Що стосується eval vs. глобальних змінних рішень ...

Я думаю, що у кожного є переваги, але це дійсно хибна дихотомія. Якщо ви параноїк глобального простору імен, просто створіть тимчасовий простір імен і використовуйте ту саму техніку.

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

tempNamespace[myString] = 5;

Досить впевнений, що потім ви могли отримати доступ як tempNamespace.myVarProperty (зараз 5), уникаючи використання вікна для зберігання. (Рядок також можна поставити прямо в дужки)


Трохи рефактор вашого коду, щоб зробити той самий вбудований var tempNamespace = {["myVarProperty"]: "Однозначно лише відео"};
Тіома

1
Це дуже вдале рішення - схоже, що eval () слід уникати, якщо це абсолютно не потрібно, дуже елегантний спосіб вирішення.
skwidbreth

Починаючи з колекції document.body.getElementsByTagName ('*'), легко знайти всі елементи, що мають атрибут 'id', і створити змінну для значення об'єкта елемента кожного з них в глобальному об’єкті 'id'. Тоді ви можете посилатися на <div id = container> у JavaScript як "id.container". Так легко!
Девід Спектор

15
var myString = "echoHello";

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

echoHello();

Не кажіть злому евалу. Приклад тут: https://jsfiddle.net/Shaz/WmA8t/


3
Зробіть цю роботу в локальному масштабі, і я зніму зворотний зв'язок.
Томаш Зато - Відновіть Моніку

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

@richmondwang this- це не відношення до локальної області, а до об'єкта, до якого функція пов'язана під час виклику.
Томаш Зато - Відновіть Моніку

8

Ви можете отримати доступ до об'єкта вікна як асоціативний масив і встановити його таким чином

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

8

Метод вікна ['змінного імені'] ТІЛЬКИ працює, якщо змінна визначена в глобальній області. Правильна відповідь - "Рефактор". Якщо ви можете надати контекст "Object", то можливе загальне рішення існує, але є деякі змінні, які жодна глобальна функція не може вирішити на основі сфери змінної.

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

6

Якщо ви намагаєтеся отримати доступ до властивості об'єкта, вам слід почати з області застосування windowта пройти через кожну властивість об'єкта, поки ви не отримаєте потрібну. Якщо припустити, що a.b.cвизначено десь ще в сценарії, ви можете використовувати наступне:

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

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

Це допоможе отримати майно будь-якого об’єкта, незалежно від того, наскільки воно глибоке.


Ваш приклад класний. Зауважу, що якщо я використовую nameяк ім'я змінної, ваш приклад виходить з ладу, але він працює з іншими іменами змінних. Це може бути пов'язано з об'єктом Window, який вже має nameзмінну. Також у тому числі .valueметод спричинив збій. Можливість інтерпретувати глибоко вкладені змінні об'єкта - це те, що я шукаю, і ваш метод вказує на хороший напрямок. Дякую.
Тео

Нема проблем. Відповідь швидше демонструє концепцію, а не копіювати / вставляти відповідь (як це більшість відповідей тут, так що я думаю)

1
Відповіді ТА навіть краще, коли Ви можете витратити час на їх вдосконалення, а не на їх виправлення. ;-)
Тео

Не працює:Uncaught TypeError: Cannot read property 'split' of undefined
Roberto14


0

Це можна зробити так

(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

Наступний код дозволяє легко посилатися на кожен свій DIV та інші елементи HTML у JavaScript. Цей код слід включити безпосередньо перед тегом, щоб усі елементи HTML були бачені. За ним повинен бути ваш код JavaScript.

// 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";
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.