#javascript
#javascript
Вопрос:
Что я хочу сделать, так это отправить данные между двумя обработчиками.
element.onmousedown = function() {
data = precalculate();
}
element.onmouseup = function() {
dosomething(data);
}
если data
это глобальная переменная, это работает. Люди говорят, что глобальная переменная — это зло. Но я не знаю, как обойтись без этого.
или я неправильно понял «глобальную переменную»?
Ответ №1:
Просто измените область видимости переменной, если вы не хотите / нуждаетесь в том, чтобы она была глобальной:
(function() {
var data;
element.onmousedown = function() {
data = precalculate();
}
element.onmouseup = function() {
dosomething(data);
}
})();
РЕДАКТИРОВАТЬ: Чтобы уточнить, единственный способ создать новую область видимости переменной в javascript — это использовать функцию.
Любая переменная, объявленная с var
внутри функции, недоступна для внешней области видимости.
В приведенном выше коде я создал IIFE (выражение функции, вызываемое немедленно), которое представляет собой просто функцию, которая вызывается сразу после ее создания, и я поместил вашу data
переменную (вместе с назначениями обработчика) внутри нее.
Поскольку обработчики были созданы в области видимости, которая имеет доступ к data
переменной, они сохраняют свой доступ к этой переменной.
Чтобы привести другой пример:
var a = "a"; // global variable
(function() {
var b = "b"; // new variable in this scope
(function() {
var c = "c"; // new variable in this scope
// in this function, you have access to 'a', 'b' and 'c'
})();
// in this function you have access to 'a' and 'b' variables, but not 'c'
})();
// globally, you have access to the 'a' variable, but not 'b' or 'c'
Комментарии:
1. @Lai: Рад, что смог помочь. Я добавил еще один пример области видимости переменной.
Ответ №2:
В этом случае глобальная переменная имела бы смысл. Другая возможность — присвоить значение элементу DOM:
element.onmousedown = function() {
// 'this' should point to the element being mouse downed
this.data = precalculate();
};
element.onmouseup = function() {
// 'this' should point to the element being mouse upped
var data = this.data;
dosomething(data);
};
Ответ №3:
Вы неправильно поняли «глобальная переменная — это зло».
На самом деле, что действительно произошло, так это то, что кто-то захотел быть «частью толпы» и поэтому сказал вам широкое обобщение, когда на самом деле они должны были сказать «используйте глобальные переменные только там, где это уместно».
Что ж, они здесь уместны, мой друг.
Комментарии:
1. Все широкие обобщения — зло! ;o)
Ответ №4:
jQuery делает это возможным с помощью функции .data():
Комментарии:
1. Нет никаких указаний на то, что здесь используется jQuery.
2. @user: Просто то, что не имеет смысла загружать целую библиотеку ради единственной потребности, которая легко решается в самом языке.
3. Я думаю, что это верный аргумент. Если решение не является хорошим, не голосуйте за него. Но пользователь специально не сказал «нет jquery».
4. @user: Да, и я не голосовал ни за, ни против. Просто подумал, что это стоит прокомментировать. jQuery может быть отличным решением, но не всегда.
5. Согласен, и для протокола, я проголосовал за ваше решение, и если бы я знал это, я бы предложил его вместо этого, но я придерживаюсь того, что знаю, пока не узнаю лучше.
Ответ №5:
Вам может сойти с рук использование глобальных переменных, если вы сведете их к минимуму, например, вы можете размещать данные в одном глобальном пространстве имен:
App = {};
element.onmousedown = function() {
App.data = "hello";
}
element.onmouseup = function() {
console.log(App.data);
}
Ответ №6:
Другим, более общим решением является создание функций, которые кэшируют свои результаты, используя метод, который называется запоминанием. При поиске есть много чего. Следующий код делает именно это :
Function.prototype.memoize = function() {
var fn = this;
this.memory = {};
return function() {
var args = Array.prototype.slice.call(arguments);
return fn.memory[args] ? fn.memory[args] : fn.memory[args] = fn.apply(this, arguments);
};
};
например, у вас есть дорогостоящая функция под названием exfunc..
newFunc = exfunc.memoize();
Приведенная выше инструкция создает новую функцию с именем newFunc, которая кэширует результат исходной функции, так что при первом выполнении фактический код и все последующие вызовы извлекаются из локального кэша.
В основном это работает с функциями, возвращаемое значение которых не зависит от глобального состояния.
Дополнительная информация: http://osteele.com/archives/2006/04/javascript-memoization