簡體   English   中英

我可以命名一個 JavaScript function 並立即執行嗎?

[英]Can I name a JavaScript function and execute it immediately?

我有很多這樣的:

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

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

重新添加事件是必要的,因為 DOM 已更改,因此之前附加的事件已不存在。 因為它們最初也必須附加(duh),所以它們在一個很好的 function 中是干的。

這個設置沒有任何問題(或者有什么問題?),但我可以稍微平滑一下嗎? 我想創建addEventsAndStuff() function 並立即調用它,所以它看起來不那么業余。

以下兩者均以語法錯誤響應:

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 (或IE上的event.srcElement )來確定事件實際發生的位置並正確處理它。

這樣,您只需附加一次處理程序,即使您更換內容,它們也會繼續工作。

以下是不使用任何幫助程序庫的事件委派示例:

(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調度,但你可以根據需要進行復雜或簡單的匹配。

現代JavaScript庫如jQueryPrototypeYUIClosure其他幾個應該提供事件委派功能,以平滑瀏覽器差異並干凈地處理邊緣情況。 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');
 })();

作品。 干杯!

[ edit ]基於評論:這應該運行並一次性返回函數:

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"

試着這樣做:

var addEventsAndStuff = (function(){
    var func = function(){
        alert('ole!');
    };
    func();
    return func;
})();

如果你想創建一個函數並立即執行 -

// 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();

對於我的應用程序,我選擇了最簡單的方法。 我只需要在頁面加載時立即觸發 function 並在其他幾個代碼部分再次使用它。

function doMyFunctionNow(){
    //for example change the color of a div
}

var flag = true;
if(flag){
    doMyFunctionNow();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM