问题描述
我需要创建一个只能执行一次的函数,在第一个之后的每次都不会执行.我从C ++和Java知道可以完成这项工作的静态变量,但我想知道是否有一种更优雅的方法?
推荐答案
如果通过"不会执行"您的意思是"您的意思是"在被调用一次不超过一次",则可以创建一个封闭:
var something = (function() { var executed = false; return function() { if (!executed) { executed = true; // do something } }; })(); something(); // "do something" happens something(); // nothing happens
在回答@vladloffe(现已删除)的评论时:使用全局变量,其他代码可以重置"执行"标志的值(无论您选择的名称如何).关闭后,其他代码无法意外或故意这样做.
正如这里的其他答案所指出的那样,几个库(例如 underscore 和 ramda )具有一个小实用功能(通常命名为once() [*] ),该函数接受函数作为参数并返回另一个函数无论返回功能多少次,它都会精确调用所提供的功能一次.返回的函数还缓存了由提供的函数首先返回的值,并在后续呼叫上返回.
但是,如果您不使用这样的第三方库,但仍然需要实用程序功能(而不是我上面提供的nonce解决方案),那么实现就很容易实现.我看过的最好的版本是大卫·沃尔什(David Walsh)发表的这一版本:
function once(fn, context) { var result; return function() { if (fn) { result = fn.apply(context || this, arguments); fn = null; } return result; }; }
我倾向于将fn = null;更改为fn = context = null;.一旦调用fn,就没有理由关闭对context的引用.
用法:
function something() { /* do something */ } var one_something = once(something); one_something(); // "do something" happens one_something(); // nothing happens
[*] 请注意,但是,其他库,例如此Drupal扩展到jQuery ,可能具有名为once()的函数,可以做一些完全不同的功能.
其他推荐答案
用可重复使用的noop (无操作)函数替换它.
// this function does nothing function noop() {}; function foo() { foo = noop; // swap the functions // do your thing } function bar() { bar = noop; // swap the functions // do your thing }
其他推荐答案
指向 empty 函数,一旦被调用:
function myFunc(){ myFunc = function(){}; // kill it as soon as it was called console.log('call once and never again!'); // your stuff here };
<button onClick=myFunc()>Call myFunc()</button>
或这样的:
var myFunc = function func(){ if( myFunc.fired ) return; myFunc.fired = true; console.log('called once and never again!'); // your stuff here }; // even if referenced & "renamed" ((refToMyfunc)=>{ setInterval(refToMyfunc, 1000); })(myFunc)
问题描述
I need to create a function which can be executed only once, in each time after the first it won't be executed. I know from C++ and Java about static variables that can do the work but I would like to know if there is a more elegant way to do this?
推荐答案
If by "won't be executed" you mean "will do nothing when called more than once", you can create a closure:
var something = (function() { var executed = false; return function() { if (!executed) { executed = true; // do something } }; })(); something(); // "do something" happens something(); // nothing happens
In answer to a comment by @Vladloffe (now deleted): With a global variable, other code could reset the value of the "executed" flag (whatever name you pick for it). With a closure, other code has no way to do that, either accidentally or deliberately.
As other answers here point out, several libraries (such as Underscore and Ramda) have a little utility function (typically named once()[*]) that accepts a function as an argument and returns another function that calls the supplied function exactly once, regardless of how many times the returned function is called. The returned function also caches the value first returned by the supplied function and returns that on subsequent calls.
However, if you aren't using such a third-party library, but still want a utility function (rather than the nonce solution I offered above), it's easy enough to implement. The nicest version I've seen is this one posted by David Walsh:
function once(fn, context) { var result; return function() { if (fn) { result = fn.apply(context || this, arguments); fn = null; } return result; }; }
I would be inclined to change fn = null; to fn = context = null;. There's no reason for the closure to maintain a reference to context once fn has been called.
Usage:
function something() { /* do something */ } var one_something = once(something); one_something(); // "do something" happens one_something(); // nothing happens
[*] Be aware, though, that other libraries, such as this Drupal extension to jQuery, may have a function named once() that does something quite different.
其他推荐答案
Replace it with a reusable NOOP (no operation) function.
// this function does nothing function noop() {}; function foo() { foo = noop; // swap the functions // do your thing } function bar() { bar = noop; // swap the functions // do your thing }
其他推荐答案
Point to an empty function once it has been called:
function myFunc(){ myFunc = function(){}; // kill it as soon as it was called console.log('call once and never again!'); // your stuff here };
<button onClick=myFunc()>Call myFunc()</button>
Or, like so:
var myFunc = function func(){ if( myFunc.fired ) return; myFunc.fired = true; console.log('called once and never again!'); // your stuff here }; // even if referenced & "renamed" ((refToMyfunc)=>{ setInterval(refToMyfunc, 1000); })(myFunc)