Доступ к переменным из других функций без использования глобальных переменных
-
03-07-2019 - |
Вопрос
Я слышал из разных мест, что глобальные переменные по своей сути неприятны и порочны, но при выполнении некоторых не объектно-ориентированных Javascript я не вижу, как их избежать.Допустим, у меня есть функция, которая генерирует число с использованием сложного алгоритма, использующего случайные числа и прочее, но мне нужно продолжать использовать это конкретное число в какой-то другой функции, которая является обратным вызовом или чем-то еще и поэтому не может быть частью той же функции.
Если первоначально сгенерированный номер является локальной переменной, он не будет доступен оттуда.Если бы функции были объектными методами, я мог бы сделать число свойством, но это не так, и изменение всей структуры программы для этого кажется несколько чрезмерно сложным.Действительно ли глобальная переменная так плоха?
Решение
Чтобы сделать переменную, вычисляемую в функции A, видимой в функции B, у вас есть три варианта:
- сделайте это глобальным,
- сделайте это свойством объекта, или
- передавайте его в качестве параметра при вызове B из A.
Если ваша программа довольно маленькая, то глобальные переменные не так уж и плохи.В противном случае я бы рассмотрел возможность использования третьего метода:
function A()
{
var rand_num = calculate_random_number();
B(rand_num);
}
function B(r)
{
use_rand_num(r);
}
Другие советы
Я думаю, что вашим лучшим выбором здесь может быть определение одинокий переменная с глобальной областью действия и сброс ваших переменных туда:
var MyApp = {}; // Globally scoped object
function foo(){
MyApp.color = 'green';
}
function bar(){
alert(MyApp.color); // Alerts 'green'
}
Никто не должен кричать на вас за то, что вы делаете что-то подобное вышеописанному.
Рассмотрите возможность использования пространств имен:
(function() {
var local_var = 'foo';
global_var = 'bar'; // this.global_var and window.global_var also work
function local_function() {}
global_function = function() {};
})();
И то , и другое local_function
и global_function
иметь доступ ко всем локальным и глобальным переменным.
Редактировать:Еще одна распространенная закономерность:
var ns = (function() {
// local stuff
function foo() {}
function bar() {}
function baz() {} // this one stays invisible
// stuff visible in namespace object
return {
foo : foo,
bar : bar
};
})();
Тот Самый return
доступ к редактируемым свойствам теперь можно получить через объект пространства имен, например ns.foo
, сохраняя при этом доступ к локальным определениям.
То, что вы ищете, технически известно как приготовление карри.
function getMyCallback(randomValue)
{
return function(otherParam)
{
return randomValue * otherParam //or whatever it is you are doing.
}
}
var myCallback = getMyCallBack(getRand())
alert(myCallBack(1));
alert(myCallBack(2));
Приведенная выше функция не является в точности каррированной, но она обеспечивает сохранение существующего значения без добавления переменных в глобальное пространство имен или требования для него какого-либо другого репозитория объектов.
Если другой функции необходимо использовать переменную, вы передаете ее функции в качестве аргумента.
Кроме того, глобальные переменные по своей сути не являются неприятными и злыми.Пока они используются должным образом, с ними нет никаких проблем.
Если есть шанс, что вы будете повторно использовать этот код, то я бы, вероятно, приложил усилия, чтобы использовать объектно-ориентированную перспективу.Использование глобального пространства имен может быть опасным - вы рискуете столкнуться с труднодоступными ошибками из-за имен переменных, которые используются повторно.Обычно я начинаю с использования объектно-ориентированного подхода для чего-то большего, чем простой обратный вызов, так что мне не нужно ничего переписывать.Я думаю, что каждый раз, когда у вас есть группа связанных функций в javascript, это кандидат на объектно-ориентированный подход.
Другой подход - это тот, который я почерпнул из сообщения Дугласа Крокфорда на форуме(http://bytes.com/topic/javascript/answers/512361-array-objects).Вот оно...
Дуглас Крокфорд писал:
Июль 15 '06
"Если вы хотите извлекать объекты по идентификатору, то вам следует использовать object, а не array.Поскольку функции также являются объектами, вы могли бы хранить элементы в самой функции ."
function objFacility(id, name, adr, city, state, zip) {
return objFacility[id] = {
id: id,
name: name,
adr: adr,
city: city,
state: state,
zip: zip
}
}
objFacility('wlevine', 'Levine', '23 Skid Row', 'Springfield', 'Il', 10010);
"Объект может быть получен с помощью"
objFacility.wlevine
Доступ к свойствам объектов теперь доступен из любой другой функции.
Я нашел это чрезвычайно полезным по отношению к первоначальному вопросу:
Верните значение, которое вы хотите использовать в functionOne, затем вызовите functionOne внутри FunctionTwo, затем поместите результат в новый var и ссылайтесь на этот новый var внутри FunctionTwo.Это должно позволить вам использовать переменную, объявленную в functionOne, внутри FunctionTwo.
function functionOne() {
var variableThree = 3;
return variableThree;
}
function functionTwo() {
var variableOne = 1;
var var3 = functionOne();
var result = var3 - variableOne;
console.log(variableOne);
console.log(var3);
console.log('functional result: ' + result);
}
functionTwo();
Я не знаю специфики вашей проблемы, но если функции нужно значение, то это может быть параметр, передаваемый через вызов.
Глобальные переменные считаются плохими, потому что состояние глобальных переменных и несколько модификаторов могут создавать трудный для понимания код и странные ошибки.Для многих актеров возня с чем-то может создать хаос.
Вы можете полностью контролировать выполнение функций javascript (и передавать переменные между ними), используя пользовательские события jQuery....Мне сказали, что это невозможно на всех этих форумах, но у меня есть кое-что работающее, что делает именно это (даже используя вызов ajax).
Вот ответ (ВАЖНЫЙ:это не проверенный ответ, а скорее мой ответ "Эмиль"):
Как получить переменную, возвращаемую несколькими функциями - Javascript / jQuery