Мне нужно создать функцию, которая может выполняться только один раз, каждый раз после первой она не будет выполняться. Я знаю из C ++ и Java о статических переменных, которые могут выполнять эту работу, но я хотел бы знать, есть ли более элегантный способ сделать это?
116
Ответы:
Если под «не будет выполняться» вы имеете в виду «ничего не будет делать при вызове более одного раза», вы можете создать закрытие:
В ответ на комментарий @Vladloffe (теперь удален): с помощью глобальной переменной другой код может сбросить значение флага «выполнено» (какое бы имя вы для него не выбрали). С закрытием другой код не имеет возможности сделать это случайно или намеренно.
Как указывают другие ответы здесь, несколько библиотек (таких как Underscore и Ramda ) имеют небольшую служебную функцию (обычно называемую
once()
[*] ), которая принимает функцию в качестве аргумента и возвращает другую функцию, которая вызывает предоставленную функцию ровно один раз, независимо от того, как много раз вызывается возвращаемая функция. Возвращенная функция также кэширует значение, которое сначала возвращает предоставленная функция, и возвращает его при последующих вызовах.Однако, если вы не используете такую стороннюю библиотеку, но все же хотите такую служебную функцию (а не одноразовое решение, которое я предложил выше), ее достаточно легко реализовать. Самая красивая версия, которую я видел, - это опубликованная Дэвидом Уолшем :
Я был бы склонен перейти
fn = null;
наfn = context = null;
. Нет причин для закрытия, чтобы поддерживать ссылку наcontext
один разfn
.[*] Однако имейте в виду, что другие библиотеки, такие как это расширение Drupal для jQuery , могут иметь функцию с именем,
once()
которая выполняет совсем другие функции.источник
if
тестовом выражении оператора) JavaScript ожидает одно из значенийtrue
или,false
и поток программы реагирует в соответствии со значением, найденным при оценке выражения. Условные операторы, такие как==
always, возвращают логическое значение. Переменная также может содержать либоtrue
илиfalse
. (Для получения дополнительной информации см. Документацию по логическим , правдивым и ложным .)Замените его многоразовой функцией NOOP (без операции) .
источник
setInterval(foo, 1000)
- и это уже не работает. Вы просто перезаписываете ссылку в текущей области.invalidate
функция, которая работает с иsetInterval
т. ДУкажите на пустую функцию после ее вызова:
Или вот так:
источник
setInterval()
), то при вызове ссылка будет повторять исходную функциональность.В UnderscoreJs есть функция, которая делает это, underscorejs.org/#once
источник
once
принимать аргументы. Вы можете сделатьsquareo = _.once(square); console.log(squareo(1)); console.log(squareo(2));
и получить1
за оба звонкаsquareo
. Я правильно понимаю?_.once
метод. См. Jsfiddle.net/631tgc5f/1_
; Я бы не рекомендовал полагаться на всю библиотеку для такого небольшого фрагмента кода.Говоря о статических переменных, это немного похоже на вариант закрытия:
Затем вы можете сбросить функцию, если хотите:
источник
источник
Вы можете просто использовать функцию «удалить себя»
Но это может быть не лучший ответ, если вы не хотите глотать ошибки.
Вы также можете сделать это:
Мне нужно, чтобы он работал как умный указатель, если нет элементов типа A, он может быть выполнен, если есть один или несколько элементов A, функция не может быть выполнена.
источник
Once
передается как обратный вызов (например,setInterval(Once, 100)
). Исходная функция будет продолжать вызываться.попробуй это
источник
От какого-то чувака по имени Крокфорд ... :)
источник
TypeError: Cannot read property 'apply' of null
это здорово. Это то, что вы получаете во второй раз, когда вызываете возвращенную функцию.Многоразовая
invalidate
функция, которая работает сsetInterval
:Попробуйте на JSBin: https://jsbin.com/vicipar/edit?js,console
Вариант ответа от Буник
источник
Вот пример JSFiddle - http://jsfiddle.net/6yL6t/
И код:
Вы могли сделать:
И запустится только один раз :)
источник
Начальная настройка:
источник
Если вы используете Node.js или пишете JavaScript с помощью browserify, подумайте о модуле npm "Once" :
источник
Если вы хотите иметь возможность повторно использовать функцию в будущем, это хорошо работает на основе приведенного выше кода Эда Хоппа (я понимаю, что исходный вопрос не требовал этой дополнительной функции!):
Результат выглядит так:
источник
простой декоратор, который легко написать, когда вам нужно
с помощью:
источник
Попытка использовать функцию подчеркивания «один раз»:
http://underscorejs.org/#once
источник
источник
Если вы используете Ramda, вы можете использовать функцию «один раз» .
Цитата из документации:
источник
будь как можно проще
Вы можете увидеть результат
источник
this
вместоwindow
JQuery позволяет вызвать функцию только один раз, используя метод one () :
Реализация с использованием метода JQuery on () :
Реализация с использованием собственного JS:
источник
источник
Это полезно для предотвращения бесконечных циклов (с использованием jQuery):
Если вас беспокоит загрязнение пространства имен, замените «doIt» длинной случайной строкой.
источник
Это помогает предотвратить липкое исполнение
источник