Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Добавление индивидуальных свойств к функции (https://javascript.ru/forum/misc/40877-dobavlenie-individualnykh-svojjstv-k-funkcii.html)

ExeiL 22.08.2013 20:09

Добавление индивидуальных свойств к функции
 
Всем привет,

Есть функция, которая делает элемент прозрачным (плавно). Соответственно хочу добавить ей свойство "в работе". И чтобы каждый экземпляр вызванной функции имел это свойство для проверки.

function fade(arg1,arg2,arg3) {
...
}

function initFade() {
  var fd1 = fade,
       fd2 = fade;

  fd1(arg1,arg2,arg3);
  alert(fd1.running + " " + fd2.running); // true false
}

initFade();


В общем как-то так, надеюсь логику работы поняли и сможете мне подсказать как правильно реализовать данный замысел...

ksa 22.08.2013 20:24

Цитата:

Сообщение от ExeiL
Есть функция
...
хочу добавить ей свойство "в работе".

У функции нет свойств...

Цитата:

Сообщение от ExeiL
каждый экземпляр вызванной функции

У функций нет экземпляров...

ExeiL 22.08.2013 20:55

Цитата:

Сообщение от ksa (Сообщение 268851)
У функции нет свойств...

function fn() {
  fn.prop = "свойств";
}
fn.propNew = "текст из ";
fn();
alert(fn.propNew + fn.prop);  // текст из свойств


Цитата:

Сообщение от ksa (Сообщение 268851)
У функций нет экземпляров...

function makeCounter() {
  var currentCount = 0;
    
  return function() {
    currentCount++;
    return currentCount;
  };
}

var counter = makeCounter();

// каждый вызов увеличивает счётчик
counter(); 
counter(); 
alert( counter() ); // 3

var c1 = makeCounter();

var c2 = makeCounter();

alert( c1() ); // 1
alert( c2() ); // 1, счётчики независимы


Похоже, что все есть...

Возможно, вы знаете способ проверки на работу функции получше, чем придумал я?

ExeiL 22.08.2013 21:36

Цитата:

Сообщение от Дзен-трансгуманист (Сообщение 268857)
Ну так fd1 = fade и fd2 = fade - это просто две ссылки на один объект, то есть экземпляр при обращении к каждой переменной один и тот же. Делайте через возврат замыкания, как со счетчиком: fd1 = makeFader().

Дак да, это понятно. Просто непонятно как связать со свойствами...
Сделал уже через замыкание, но вдруг кто знает как связать со свойствами или еще более лучшее решение...

ExeiL 22.08.2013 22:56

Цитата:

Сообщение от Дзен-трансгуманист (Сообщение 268859)
function makeFader() {

  function fade (arg1,arg2,arg3) {
    fade.running = true;
  }

  fade.running = false;
  return fade;
}

о, точно. Спасибо!
Теперь не придется лишний раз выполнять функцию для возврата переменной.

ksa 23.08.2013 08:47

Цитата:

Сообщение от ExeiL
Похоже, что все есть...

Экземпляров точно нет... :)
Это только копирование ссылки на объект.

Да и свойства те, не свойства функции... Это свойства объекта ссылка на который хранится в той же переменной, что и на функцию.

ksa 23.08.2013 08:52

Хотя из первоисточника
Цитата:

В javascript функции являются полноценными объектами встроенного класса Function. Именно поэтому их можно присваивать переменным, передавать и, конечно, у них есть свойства
http://javascript.ru/basic/functions#funkcii---obekty

Т.ч. свойства есть. :yes:

Но экземпляры делает только new или нечто аналогичное...

ExeiL 23.08.2013 09:18

Цитата:

Сообщение от ksa (Сообщение 268881)
Хотя из первоисточника

http://javascript.ru/basic/functions#funkcii---obekty

Т.ч. свойства есть. :yes:

Но экземпляры делает только new или нечто аналогичное...

Кстати, не понятно как лучше: делать объект с функциями и потом использовать new или делать функции с замыканием - как выше... по сути выполняться будет someFunction.someMethod() и там и там...

function SomeFn() {
  this.someMethod = function() {
    alert("hi");
  };
}

var someFunction = new SomeFn;
someFunction.someMethod();


или

function someFn() {
  function sfn() {
    return;
  }

  sfn.someMethod = function() {
    alert("hi");
  }

  return sfn;
}

var someFunction = someFn();
someFunction.someMethod();

ksa 23.08.2013 09:26

Цитата:

Сообщение от ExeiL
как лучше

Это наверное больше философский вопрос...

Что есть "лучше"?
Например есть несколько вариантов реализации нужного тебе эффекта... Какой лучше?
- работает быстрее?
- текст реализации выглядит понятнее, симпатичнее?
- менее ресурсоемок?

ksa 23.08.2013 09:31

Цитата:

Сообщение от ExeiL
someFunction = someFn()

По мне так это масло масляное... :)
1 объект/экземпляр и две переменные со ссылкой на него...

Цитата:

Сообщение от ExeiL
var someFunction = new SomeFn;

А тут четко создается объект/экземпляр класса SomeFn.

ExeiL 23.08.2013 09:48

Цитата:

Сообщение от ksa (Сообщение 268888)
По мне так это масло масляное... :)
1 объект/экземпляр и две переменные со ссылкой на него...

Ну не совсем, в "someFunction = someFn()" идет сначала выполнение someFn (так сказать подготовка), а потом присвоение результата - свежеиспеченный экземпляр функции...

ksa 23.08.2013 09:50

Цитата:

Сообщение от ExeiL
Ну не совсем

О, точно. :yes:

Но с new оно как-то по коду лучше и явно представлено...

ExeiL 23.08.2013 12:02

Минусы объекта:
- this. надо сохранять перед передачей в setTimeout
- при вызове метода из SetTimeout надо обрамлять в function(){ } // Решается добавлением "var savedThis = this;" в начало функции и последующем использовании savedThis вместо this. (не уверен в кроссбраузерности)

Пример:
function SomeFn() {
  this.info = "Если видно, значит инфо доступно";

  this.someShow = function() {
    var savedThis = this;
    setTimeout(function(){ alert(savedThis.info); }, 10);  // Если написать this.info, получим undefined
  };
}

var someFunction = new SomeFn;
setTimeout(function(){ someFunction.someShow(); }, 10); // Если написать setTimeout(someFunction.someShow, 10), получим undefined


PS: По скорости разницы с замыканием при тестах не заметил...

ksa 23.08.2013 13:06

ExeiL, вот и думай что есть для тебя "лучше"... :)

ExeiL 23.08.2013 13:33

Цитата:

Сообщение от ksa (Сообщение 268928)
ExeiL, вот и думай что есть для тебя "лучше"... :)

Выбрал объект, т.к. разница между замыканием только в том, что он не возвращает при someFunction(); ибо [object Object], а не [object Function]...

Когда надо будет использовать функцию напрямую - замыкание, когда не надо - объект)


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