[javascript] 한 번만 호출 할 수있는 JavaScript 함수

한 번만 실행할 수있는 함수를 만들어야합니다. 처음 이후에는 매번 실행되지 않습니다. 작업을 수행 할 수있는 정적 변수에 대해 C ++ 및 Java에서 알고 있지만이를 수행하는 더 우아한 방법이 있는지 알고 싶습니다.



답변

“실행되지 않음”이 “두 번 이상 호출 될 때 아무것도하지 않음”을 의미하는 경우 클로저를 만들 수 있습니다.

var something = (function() {
    var executed = false;
    return function() {
        if (!executed) {
            executed = true;
            // do something
        }
    };
})();

something(); // "do something" happens
something(); // nothing happens

@Vladloffe (현재 삭제됨)의 주석에 대한 답변 : 전역 변수를 사용하면 다른 코드에서 “executed”플래그의 값을 재설정 할 수 있습니다 (선택한 이름에 관계없이). 클로저를 사용하면 다른 코드는 실수로 또는 고의로 그렇게 할 수 없습니다.

여기에서 다른 답변이 지적했듯이 여러 라이브러리 (예 : UnderscoreRamda )에는 함수를 인수로 받아들이고 제공된 함수를 정확히 한 번 호출하는 다른 함수를 반환 하는 작은 유틸리티 함수 (일반적으로 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; . 클로저가 context한 번에 대한 참조를 유지할 이유가 없습니다 fn.

[*] 하지만, jQuery에 대한 Drupal 확장 과 같은 다른 라이브러리에는 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
}


답변

호출되면 함수를 가리 킵니다 .

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)


답변

UnderscoreJs에는 underscorejs.org/#once 라는 기능이 있습니다.

  // Returns a function that will be executed at most one time, no matter how
  // often you call it. Useful for lazy initialization.
  _.once = function(func) {
    var ran = false, memo;
    return function() {
      if (ran) return memo;
      ran = true;
      memo = func.apply(this, arguments);
      func = null;
      return memo;
    };
  };


답변

정적 변수에 대해 말하면 이것은 클로저 변형과 약간 비슷합니다.

var once = function() {
    if(once.done) return;
    console.log('Doing this once!');
    once.done = true;
};

once(); once(); 

원하는 경우 기능을 재설정 할 수 있습니다.

once.done = false;


답변

var quit = false;

function something() {
    if(quit) {
       return;
    }
    quit = true;
    ... other code....
}


답변

단순히 “자체 제거”기능을 사용할 수 있습니다.

function Once(){
    console.log("run");

    Once = undefined;
}

Once();  // run
Once();  // Uncaught TypeError: undefined is not a function 

그러나 오류를 삼키고 싶지 않다면 이것이 최선의 대답이 아닐 수도 있습니다.

다음과 같이 할 수도 있습니다.

function Once(){
    console.log("run");

    Once = function(){};
}

Once(); // run
Once(); // nothing happens

유형 A의 요소가 없으면 실행할 수 있고 하나 이상의 A 요소가 있으면 함수를 실행할 수없는 스마트 포인터처럼 작동해야합니다.

function Conditional(){
    if (!<no elements from type A>) return;

    // do stuff
}