Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Проверка повторного вызова функции без глобальных переменных (https://javascript.ru/forum/misc/46082-proverka-povtornogo-vyzova-funkcii-bez-globalnykh-peremennykh.html)

GlaIZier 27.03.2014 14:45

Проверка повторного вызова функции без глобальных переменных
 
Здравствуйте!

Подскажите, пожалуйста, можно ли проверить, была ли вызвана функция, без использования глобальных переменных?

Написал функцию на чистом JS, привязанную к кнопке и отвечающую за анимацию.
var animate = function(animationVar) {
   animationVar = animationVar || 0;
   if (animationVar > CONST) return;
   window.setTimeout(function () {
      animate(animationVar + 1);
   }, 50);
}

Соответсвенно, если нажать два раза анимация ускоряется. Можно ли как-то сделать проверку, была ли уже вызвана функция?
Можно поставить глобальную переменную и проверять ее внутри функции, но хотелось бы сделать изящнее. Смотрел в сторону замыканий, но так ничего и не смог придумать, чтобы работало, как надо.

Спасибо.

ksa 27.03.2014 14:58

Цитата:

Сообщение от GlaIZier
можно ли проверить, была ли вызвана функция, без использования глобальных переменных?

Как вариант...

function test(){
	alert('Вызывалась '+(arguments.callee.count++));
};
test.count=0;
test();
test();
test();

GlaIZier 27.03.2014 16:32

Спасибо большое! Это должно помочь. Единственная проблема, что в моем примере происходит рекурсивный вызов. Как проверить, была ли функция вызвана изнутри или снаружи, если вызов проиходит по одинаковому имени?

GOD 27.03.2014 20:47

GlaIZier,

arguments.callee устаревшее свойсвтво которое скоро удалят, для того чтобы обратиться к самой функции, изнутри её самой, надо использовать её имя:

function test(){
	alert('Вызывалась '+(test.count++));
};
test.count=0;
test();
test();
test();



ksa не очень разбирается в стандартах по этому дал тебе вредный совет. Так же не стоит бояться что это название перекроется, имя функции попадает в замыкание функции если используется внутри, подобно аргументам) так что бояться не стоит.


q = function cat(){
    alert(cat)
}

cat = 11;
q() // выведет не 11

ksa 27.03.2014 20:48

Цитата:

Сообщение от GlaIZier
Как проверить, была ли функция вызвана изнутри или снаружи

Сделай два свойства input и output...

function test(){
	arguments.callee.out++;
	alert('Вызывалась '+(arguments.callee.out-arguments.callee.in)+' внешне и '+arguments.callee.in+' внутренне');
	if (arguments.callee.out==2) {
		test.in++;
		test();
	};
};
test.in=0;
test.out=0;
test();
test();
test();

ksa 27.03.2014 20:49

Цитата:

Сообщение от GOD
не очерь разбирается в стандартах по этому дал тебе вредный совет

Хорошо, что у нас есть ты... :D

ksa 27.03.2014 20:50

Цитата:

Сообщение от GOD
так что бояться не стоит

Я уже не боюсь... :D

GOD 27.03.2014 20:57

Не слушай ksa, он дает вредные советы. Передавай динамические данные вглубь рекурсии, тогда ты будешь знать уровень на котором находится рекурсия, например если мы на нуливом уровне, значит функция вызванна извне.



function rec(deep) {

    if(!deep) deep = 0; // по умолчанию глубина 0

    if (deep > 5) {
        alert('глубина рекурсии больше 5, дальше не пойдем, всплываем');
        return; // всплываем
    }


    alert('глубина рекурсии: ' + deep);

    // погружаемся
    // когда идем вглубь, прибавляем индекс глубины на 1
    rec(deep + 1);

    // всплываем
    alert('всплываем, и мы на уровне: ' + deep);

}



rec()

ksa 27.03.2014 21:42

Цитата:

Сообщение от GOD
Не слушай ksa, он дает вредные советы.

Куда мне до твоего "решения"... :D

GOD 27.03.2014 21:45

ksa, Так говоришь как будто я не лучше тебя программирую.

Vlasenko Fedor 28.03.2014 03:52

лучший г....кодер - это я:haha:
var foo = function () {
	alert(this.exec ? "Уже запускалось" : "Первый раз");
	this.exec = true;
};
foo();
foo();

jsnb 28.03.2014 04:01

Цитата:

Сообщение от Poznakomlus (Сообщение 304809)
var foo = function () {
	alert(this.exec ? "Уже запускалось" : "Первый раз");
	this.exec = true;
};
foo();

Просили ж без глобальных переменных.

Vlasenko Fedor 28.03.2014 04:12

Цитата:

Сообщение от jsnb (Сообщение 304810)
Просили ж без глобальных переменных.

если вы хотите избавится от глобальных переменных, функций, объектов, оберните свой код в
(function () {
//здесь код
}());
:p

jsnb 28.03.2014 04:22

Цитата:

Сообщение от Poznakomlus (Сообщение 304811)
если вы хотите избавится от глобальных переменных и функций оберните свой код в
(function () {
//здесь код
}());
:p

Не поможет:
(function () {
  var foo = function () {
    alert(this.exec ? "Уже запускалось" : "Первый раз");
    this.exec = true;
  };
  foo();
}());

alert(exec);

Vlasenko Fedor 28.03.2014 04:37

jsnb,
эт ты прав оказался, тогда так
var foo = function () {
  alert(foo.exec ? "Уже запускалось" : "Первый раз");
  foo.exec = true;
};
foo();
foo();
alert(exec);

и соответственно
(function () {
  function foo() {
    alert(foo.exec ? "Уже запускалось" : "Первый раз");
    foo.exec = true;
  };
foo();
foo();
}());
alert(foo.exec);
alert(exec);

ksa 28.03.2014 08:37

GOD, я тебя даже не знаю... :D

GOD 28.03.2014 13:02

ksa, а говоришь так, будто я не лучше программист чем ты) хотя наши коды доказывают что я лучше тебя программирую. ты просто сарказмнул так на счет моих примеров БУДТО ОНИ ХУЖЕ твоих) я и удивился.

ksa 28.03.2014 13:19

Цитата:

Сообщение от GOD
наши коды доказывают что я лучше тебя программирую

Флаг тебе в руки...

GOD 28.03.2014 13:26

:victory:

GlaIZier 28.03.2014 15:41

Всем огромное спасибо за помощь. Я посмотрю, что можно применить на выходных или в понедельник.

nerv_ 28.03.2014 17:23

Цитата:

Сообщение от GOD
наши коды доказывают что я лучше тебя программирую

Цитата:

Сообщение от ksa (Сообщение 304866)
Флаг тебе в руки...

... барабан на шею и билет в один конец :)

GlaIZier 29.03.2014 20:31

Спасибо еще раз. Сделал так:
var animate = function foo(animationVar) {
   if (typeof (foo.inside) === "undefined" && typeof (foo.outside) === "undefined" {
       foo.outside = 0;
       foo.inside = 0; 
   }
   foo.outside++;
   ...
   foo.inside++;
   if (foo.outside !== foo.inside) return;
   window.setTimeout(function() {animate(animationvar + 1);}, 50);
}


Часовой пояс GMT +3, время: 01:19.