Другое решение состоит в том, чтобы выполнить код через последовательный исполнитель nsynjs .
nsynjs будет последовательно оценивать все обещания и ставить обещания результат в свойство data
:
function synchronousCode() {
var getURL = function(url) {
return window.fetch(url).data.text().data;
};
var url = 'https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js';
console.log('received bytes:',getURL(url).length);
};
nsynjs.run(synchronousCode,{},function(){
console.log('synchronousCode done');
});
Шаг 1. Wrap с обратным вызовом в оболочку, совместимую с nsynjs (если у нее есть обещанная версия, вы можете пропустить этот тест):
var ajaxGet = function (ctx,url) {
var res = {};
var ex;
$.ajax(url)
.done(function (data) {
res.data = data;
})
.fail(function(e) {
ex = e;
})
.always(function() {
ctx.resume(ex);
});
return res;
};
ajaxGet.nsynjsHasCallback = true;
Шаг 2. Вставить синхронную логику в функцию:
function process() {
console.log('got data:', ajaxGet(nsynjsCtx, "data/file1.json").data);
}
Шаг 3. Выполнить функцию синхронно через nnsynjs:
nsynjs.run(process,this,function () {
console.log("synchronous function finished");
});
Nsynjs будет оценивать все операторы и выражения шаг за шагом, приостанавливая выполнение в случае, если результат некоторой медленной функции не готов.
Дополнительные примеры здесь: https://github.com/amaksr/nsynjs/tree/master/examples
Для этого нет единственного решения (ну, есть eval
, но не стоит серьезно относиться к этому). Доступ к глобальным переменным возможен динамически через window
, но это не работает для переменных, локальных для функции.
Почти всегда есть лучшее решение, чем использование переменных переменных! Вместо этого вы должны смотреть на структуры данных и выбирать правильную для своей проблемы.
Если у вас есть фиксированный набор имен, например
// BAD
var foo = 42;
var bar = 21;
var key = 'foo';
console.log(eval(key));
сохранить эти имена / значения в качестве свойств объекта и использовать нотацию скобки для динамического поиска:
// GOOD
var obj = {
foo: 42,
bar: 21,
};
var key = 'foo';
console.log(obj[key]);
Если у вас есть «последовательные» нумерованные переменные, такие как
// BAD
var foo1 = 'foo';
var foo2 = 'bar';
var foo3 = 'baz';
var index = 1;
console.log(eval('foo' + index));
, тогда вы должны использовать массив и просто использовать индекс для доступа к соответствующему значению:
// GOOD
var foos = ['foo', 'bar', 'baz'];
var index = 1;
console.log(foos[index - 1]);
Вы можете использовать функцию JavaScript eval(str)
.
Что эта функция делает, это преобразовать строку, предоставленную в JS-код, а затем выполняет ее.
Например:
eval("console.log('hello world')"); // Logs hello world
Итак, чтобы использовать его как переменную переменную, вы можете сделать следующее:
var a = "hello";
var hello = "world";
console.log(a + " " + eval(a)); // Logs hello world
Это даст тот же результат, что и:
console.log(a + " " + hello); // Logs hello world
(Пример из руководства PHP по переменным переменным .)
Чтобы ссылаться на переменную в javascript только с помощью строки, вы можете использовать
window['your_variable_name']
. Вы можете также устанавливать и ссылаться на переменные и объекты в переменных.
Конечно, можете, но не надо. Переменные должны быть глобальными.
var killingFunction = 'alert'
var killMeNow = 'please'
var please = 'You have been killed!'
this[killingFunction](this[killMeNow])
var vars = {};
var var_name = "str";
vars[var_name] = "working";
console.log(vars["str"]);
Если вы отчаянно хотите сделать это, вы можете либо попробовать использовать eval ():
var data = "testVariable";
eval("var temp_" + data + "=123;");
alert(temp_testVariable);
, либо использовать оконный объект:
var data = "testVariable";
window["temp_" + data] = 123;
alert(window["temp_" + data]);
http: //www.hiteshagrawal.com/javascript/dynamic-variables-in-javascript
В отличие от PHP, JavaScript не предоставляет доступ к массиву globals (который содержит ссылки на все объявленные имена переменных). Таким образом, JavaScript не предлагает встроенную поддержку переменных переменных. Вы можете, однако, эмулировать эту функцию, пока вы определяете все свои переменные как часть массива или объекта. Это, в свою очередь, создаст для вас массив злодеев. Например, вместо объявления переменной hello
в глобальной области видимости следующим образом:
var hello = 'hello world';
давайте инкапсулируем ее внутри объекта. Мы будем называть этот объект vv (переменными переменными):
var vv = {
'hello': 'hello world',
//Other variable variables come here.
},
referToHello = 'hello';
Теперь мы можем ссылаться на переменную по ее индексу, и поскольку индексы массива могут быть предоставлены с использованием переменной, мы фактически используем переменная переменная:
console.log(vv[referToHello]); //Output: hello world
Ответ на ваш вопрос
Давайте применим это к коду, указанному в исходном вопросе:
var vv = {
'x': 'variable',
'variable': 'hello world!'
};
console.log(vv[vv['x']]); //Displays "hello, world!"
A Практическое использование
Хотя предыдущий код может показаться смехотворно громоздким и непрактичным, существуют практические применения переменных переменных в JavaScript с использованием такого типа инкапсуляции. В приведенном ниже примере мы используем ту же концепцию, чтобы получить идентификатор неопределенного количества элементов HTML.
var elementIds = [],
elements = ['message','fillOrStroke','sizePicker','colorPicker']; //The items in this array could be defined automatically via an input, database query, event, etc.
elements.forEach( (element) => {
elementIds[element] = document.getElementById(element);
});
В этом примере объявляются переменные переменные (ключи в elementIds
) на основе идентификатора каждого элемента , и назначит узел упомянутого элемента как значение каждой переменной. И поскольку использование глобальных переменных в JavaScript, как правило, не рекомендуется, если переменные переменные являются уникальной областью (в этом случае, объявив их внутри массива elementIds
) не только аккуратно, но и более ответственным.