Доступ к переменным из других функций без использования глобальных переменных
Я слышал из разных мест, что глобальные переменные по своей природе являются отвратительными и злыми, но при выполнении некоторого не-объектно-ориентированного Javascript я не вижу, как их избежать. Скажем, у меня есть функция, которая генерирует число, используя сложный алгоритм, используя случайные числа и прочее, но мне нужно продолжать использовать этот конкретный номер в какой-либо другой функции, которая является обратным вызовом или чем-то другим, и поэтому не может быть частью одной и той же функции.
Если первоначально сгенерированное число является локальной переменной, оно не будет доступно из него. Если бы функции были объектными методами, я мог бы сделать свойство number a, но это не так, и кажется, что это слишком сложно, чтобы изменить всю структуру программы, чтобы сделать это. Действительно ли глобальная переменная настолько плоха?
Ответы
Ответ 1
Чтобы сделать переменную, вычисленную в функции A видимой в функции B, у вас есть три варианта:
- сделать его глобальным,
- сделать свойство объекта или
- передайте его как параметр при вызове B из A.
Если ваша программа довольно мала, то глобальные переменные не так уж плохи. В противном случае я бы рассмотрел использование третьего метода:
function A()
{
var rand_num = calculate_random_number();
B(rand_num);
}
function B(r)
{
use_rand_num(r);
}
Ответ 2
Я думаю, что лучше всего здесь можно определить одну переменную с глобальным охватом и сбросить туда свои переменные:
var MyApp = {}; // Globally scoped object
function foo(){
MyApp.color = 'green';
}
function bar(){
alert(MyApp.color); // Alerts 'green'
}
Никто не должен кричать на вас за то, что вы делаете что-то вроде выше.
Ответ 3
Рассмотрим использование пространств имен:
(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
ed можно получить через объект пространства имен, например. ns.foo
, сохраняя при этом доступ к локальным определениям.
Ответ 4
То, что вы ищете, технически известно как currying.
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));
Вышеупомянутая функция не является точно выраженной, но она достигает результата сохранения существующего значения без добавления переменных в глобальное пространство имен или требует для него другого репозитория объектов.
Ответ 5
Если другой функции нужно использовать переменную, вы передаете ее функции в качестве аргумента.
Также глобальные переменные не являются по своей природе противными и злыми. Пока они используются правильно, с ними нет проблем.
Ответ 6
Другой подход - это тот, который я поднял с сообщения форума Douglas Crockford (http://bytes.com/topic/javascript/answers/512361-array-objects). Вот оно...
Дуглас Крокфорд писал (а):
Июль 15 '06
"Если вы хотите получить объекты по id, то вы должны использовать объект, а не
массив. Поскольку функции также являются объектами, вы можете сохранить элементы в
самой функции. "
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
Теперь свойства объектов теперь доступны из любой другой функции.
Ответ 7
Я нашел, что это очень полезно в отношении исходного вопроса:
Верните значение, которое вы хотите использовать в functionOne, затем вызовите функциюOne внутри функцииTwo, затем поместите результат в новый var и ссылайтесь на этот новый var внутри функцииTwo. Это должно позволить вам использовать var, объявленный в functionOne, внутри функцииTwo.
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();
Ответ 8
Если у вас есть шанс, что вы будете повторно использовать этот код, я бы, вероятно, приложил все усилия для объектно-ориентированной перспективы. Использование глобального пространства имен может быть опасным - вы рискуете трудно найти ошибки из-за имен переменных, которые используются повторно. Обычно я начинаю с использования объектно-ориентированного подхода для чего-то большего, чем простой обратный вызов, так что мне не нужно делать перезаписи. Каждый раз, когда у вас есть группа связанных функций в javascript, я думаю, это кандидат на объектно-ориентированный подход.
Ответ 9
Я не знаю специфики вашей проблемы, но если функция нуждается в значении, это может быть параметр, пройденный по вызову.
Глобалы считаются плохими, поскольку состояние глобалов и несколько модификаторов могут создавать сложный код и странные ошибки. Для многих актеров, играющих с чем-то, можно создать хаос.
Ответ 10
Вы можете полностью контролировать выполнение функций javascript (и передавать переменные между ними) с помощью пользовательских событий jQuery.... Мне сказали, что это невозможно на всех этих форумах, но у меня есть что-то работающее, которое делает именно это (даже используя вызов ajax).
Здесь ответ (ВАЖНО: это не проверенный ответ, а скорее ответ от меня "Эмиль" ):
Как получить переменную, возвращаемую несколькими функциями - Javascript/jQuery
Ответ 11
function funA() {
return {x: "funAX"}
}
//
function funB() {
let r = funA();
console.error(r.x);
}
var x = "global x";
funB(); // funAX