[javascript] JavaScript 함수의 이름을 지정하고 즉시 실행할 수 있습니까?

나는 이것들 중 꽤있다 :

function addEventsAndStuff() {
  // bla bla
}
addEventsAndStuff();

function sendStuffToServer() {
  // send stuff
  // get HTML in response
  // replace DOM
  // add events:
  addEventsAndStuff();
}

DOM이 변경 되었기 때문에 이벤트를 다시 추가해야하므로 이전에 첨부 된 이벤트가 사라집니다. 초기에도 부착해야하므로 (duh) DRY 기능이 좋다.

이 설정에는 아무런 문제가 없습니다 (또는 거기에 있습니까?). 조금 부드럽게 할 수 있습니까? addEventsAndStuff()함수 를 생성 하고 즉시 호출하고 싶어서 그렇게 아마추어 적으로 보이지 않습니다.

다음 두 가지 모두 구문 오류로 응답합니다.

function addEventsAndStuff() {
  alert('oele');
}();

(function addEventsAndStuff() {
  alert('oele');
})();

수취인이 있습니까?



답변

질문에 게시 한 예제에는 문제가 없습니다. 다른 방법은 이상하게 보일 수 있지만 다음과 같습니다.

var addEventsAndStuff;
(addEventsAndStuff = function(){
    // add events, and ... stuff
})();

JavaScript에서 함수를 정의하는 방법에는 두 가지가 있습니다. 함수 선언 :

function foo(){ ... }

이고 함수식, 임의의 상기 이외의 함수를 정의하는 방법 :

var foo = function(){};
(function(){})();
var foo = {bar : function(){}};

…기타

함수 표현식은 이름을 지정할 수 있지만 그 이름은 포함하는 범위로 전파되지 않습니다. 이 코드가 유효 함을 의미합니다.

(function foo(){
   foo(); // recursion for some reason
}());

그러나 이것은 아닙니다 :

(function foo(){
    ...
}());
foo(); // foo does not exist

따라서 함수의 이름을 지정하고 즉시 호출하려면 지역 변수를 정의하고 함수를 표현식으로 할당 한 다음 호출해야합니다.


답변

이것에 대한 좋은 속기가 있습니다 (함수 할당에 변수를 선언 할 필요가 없습니다) :

var func = (function f(a) { console.log(a); return f; })('Blammo')


답변

이 설정에는 아무런 문제가 없습니다 (또는 거기에 있습니까?). 조금 부드럽게 할 수 있습니까?

대신 이벤트 위임을 사용하십시오. 여기서 사라 지지 않는 컨테이너에서 이벤트를 실제로 관찰 한 다음 event.target(또는 event.srcElementIE에서) 이벤트가 실제로 발생한 위치를 파악하고 올바르게 처리합니다.

이렇게하면 핸들러를 한 번만 연결하면 콘텐츠를 교체해도 계속 작동합니다.

다음은 도우미 라이브러리를 사용하지 않는 이벤트 위임의 예입니다.

(function() {
  var handlers = {};

  if (document.body.addEventListener) {
    document.body.addEventListener('click', handleBodyClick, false);
  }
  else if (document.body.attachEvent) {
    document.body.attachEvent('onclick', handleBodyClick);
  }
  else {
    document.body.onclick = handleBodyClick;
  }

  handlers.button1 = function() {
    display("Button One clicked");
    return false;
  };
  handlers.button2 = function() {
    display("Button Two clicked");
    return false;
  };
  handlers.outerDiv = function() {
    display("Outer div clicked");
    return false;
  };
  handlers.innerDiv1 = function() {
    display("Inner div 1 clicked, not cancelling event");
  };
  handlers.innerDiv2 = function() {
    display("Inner div 2 clicked, cancelling event");
    return false;
  };

  function handleBodyClick(event) {
    var target, handler;

    event = event || window.event;
    target = event.target || event.srcElement;

    while (target && target !== this) {
      if (target.id) {
        handler = handlers[target.id];
        if (handler) {
          if (handler.call(this, event) === false) {
            if (event.preventDefault) {
              event.preventDefault();
            }
            return false;
          }
        }
      }
      else if (target.tagName === "P") {
        display("You clicked the message '" + target.innerHTML + "'");
      }
      target = target.parentNode;
    }
  }

  function display(msg) {
    var p = document.createElement('p');
    p.innerHTML = msg;
    document.body.appendChild(p);
  }

})();

라이브 예

페이지에 동적으로 추가되는 메시지를 클릭하면 추가되는 새 단락에 이벤트를 연결하는 코드가 없더라도 클릭이 등록되고 처리됩니다. 또한 핸들러가 맵의 항목 일 뿐이며 모든 디스패치를 ​​수행 하는 핸들러 가 하나document.body 있습니다. 이제, 당신은 아마도 이것을보다 더 표적화 된 것에 뿌리 document.body를 내릴 것입니다. 그러나 당신은 아이디어를 얻습니다. 또한 위의 경우 기본적으로로 발송하고 id있지만 원하는대로 복잡하거나 간단하게 매칭 할 수 있습니다.

jQuery , Prototype , YUI , Closure 또는 기타 여러 가지 와 같은 최신 JavaScript 라이브러리는 브라우저 차이를 완화하고 가장자리 사례를 깔끔하게 처리 할 수있는 이벤트 위임 기능을 제공해야합니다. jQuery는 livedelegate함수 를 모두 사용하므로 전체 범위의 CSS3 선택기 (및 일부)를 사용하여 핸들러를 지정할 수 있습니다.

예를 들어, 다음은 jQuery를 사용하는 동등한 코드입니다 (jQuery가 위의 최신 원시 버전이 처리하지 않는 경우를 제외하고는 예외입니다).

(function($) {

  $("#button1").live('click', function() {
    display("Button One clicked");
    return false;
  });
  $("#button2").live('click', function() {
    display("Button Two clicked");
    return false;
  });
  $("#outerDiv").live('click', function() {
    display("Outer div clicked");
    return false;
  });
  $("#innerDiv1").live('click', function() {
    display("Inner div 1 clicked, not cancelling event");
  });
  $("#innerDiv2").live('click', function() {
    display("Inner div 2 clicked, cancelling event");
    return false;
  });
  $("p").live('click', function() {
    display("You clicked the message '" + this.innerHTML + "'");
  });

  function display(msg) {
    $("<p>").html(msg).appendTo(document.body);
  }

})(jQuery);

라이브 카피


답변

다음과 같은 도우미 함수를 만들 수 있습니다.

function defineAndRun(name, func) {
    window[name] = func;
    func();
}

defineAndRun('addEventsAndStuff', function() {
    alert('oele');
});


답변

코드에 오타가 있습니다.

(function addEventsAndStuff() {
  alert('oele');
)/*typo here, should be }*/)();

그래서

(function addEventsAndStuff() {
  alert('oele');
 })();

공장. 건배!

주석을 기반으로 [ 편집 ] : 그리고 이것은 한 번에 함수를 실행하고 반환해야합니다.

var addEventsAndStuff = (
 function(){
  var addeventsandstuff =  function(){
    alert('oele');
  };
  addeventsandstuff();
  return addeventsandstuff;
 }()
);


답변

ES6를 사용하면 더 간단합니다.

var result = ((a, b) => `${a} ${b}`)('Hello','World')
// result = "Hello World"
var result2 = (a => a*2)(5)
// result2 = 10
var result3 = (concat_two = (a, b) => `${a} ${b}`)('Hello','World')
// result3 = "Hello World"
concat_two("My name", "is Foo")
// "My name is Foo"


답변

함수를 생성하고 즉시 실행하려면-

// this will create as well as execute the function a()
(a=function a() {alert("test");})();

// this will execute the function a() i.e. alert("test")
a();