简体   繁体   English

我可以命名一个 JavaScript function 并立即执行吗?

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

I have quite a few of these:我有很多这样的:

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

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

Re-adding the events is necessary because the DOM has changed, so previously attached events are gone.重新添加事件是必要的,因为 DOM 已更改,因此之前附加的事件已不存在。 Since they have to be attached initially as well (duh), they're in a nice function to be DRY.因为它们最初也必须附加(duh),所以它们在一个很好的 function 中是干的。

There's nothing wrong with this set up (or is there?), but can I smooth it a little bit?这个设置没有任何问题(或者有什么问题?),但我可以稍微平滑一下吗? I'd like to create the addEventsAndStuff() function and immediately call it, so it doesn't look so amateuristic.我想创建addEventsAndStuff() function 并立即调用它,所以它看起来不那么业余。

Both following respond with a syntax error:以下两者均以语法错误响应:

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

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

Any takers?有接盘者吗?

There's nothing wrong with the example you posted in your question.. The other way of doing it may look odd, but: 您在问题中发布的示例没有任何问题。另一种方式可能看起来很奇怪,但是:

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

There are two ways to define a function in JavaScript. 有两种方法可以在JavaScript中定义函数。 A function declaration: 功能声明:

function foo(){ ... }

and a function expression, which is any way of defining a function other than the above: 和函数表达式,它是定义除上述之外的函数的任何方式:

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

...etc ...等等

function expressions can be named, but their name is not propagated to the containing scope. 函数表达式可以命名,但它们的名称不会传播到包含范围。 Meaning this code is valid: 这个代码的含义是有效的:

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

but this isn't: 但这不是:

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

So in order to name your function and immediately call it, you need to define a local variable, assign your function to it as an expression, then call it. 因此,为了命名您的函数并立即调用它,您需要定义一个局部变量,将您的函数作为表达式分配给它,然后调用它。

这有一个很好的简写(不需要声明任何变量来阻止函数的赋值):

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

There's nothing wrong with this set up (or is there?), but can I smooth it a little bit? 这个设置没有什么问题(或者有吗?),但我可以稍微平滑一下吗?

Look at using event delegation instead. 请查看使用事件委派。 That's where you actually watch for the event on a container that doesn't go away, and then use event.target (or event.srcElement on IE) to figure out where the event actually occurred and handle it correctly. 这就是你实际上在一个不会消失的容器上观察事件的地方,然后使用event.target (或IE上的event.srcElement )来确定事件实际发生的位置并正确处理它。

That way, you only attach the handler(s) once, and they just keep working even when you swap out content. 这样,您只需附加一次处理程序,即使您更换内容,它们也会继续工作。

Here's an example of event delegation without using any helper libs: 以下是不使用任何帮助程序库的事件委派示例:

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

})();

Live example 实例

Note how if you click the messages that get dynamically added to the page, your click gets registered and handled even though there's no code to hook events on the new paragraphs being added. 请注意,如果单击动态添加到页面的消息,即使没有代码可以挂钩添加的新段落上的事件,您的点击也会被注册和处理。 Also note how your handlers are just entries in a map, and you have one handler on the document.body that does all the dispatching. 另请注意您的处理程序如何只是地图中的条目,并且您在document.body上有一个处理程序,它执行所有调度。 Now, you probably root this in something more targeted than document.body , but you get the idea. 现在,您可能将其置于比document.body更具针对性的东西中,但您明白了。 Also, in the above we're basically dispatching by id , but you can do matching as complex or simple as you like. 另外,在上面我们基本上是通过id调度,但你可以根据需要进行复杂或简单的匹配。

Modern JavaScript libraries like jQuery , Prototype , YUI , Closure , or any of several others should offer event delegation features to smooth over browser differences and handle edge cases cleanly. 现代JavaScript库如jQueryPrototypeYUIClosure其他几个应该提供事件委派功能,以平滑浏览器差异并干净地处理边缘情况。 jQuery certainly does, with both its live and delegate functions, which allow you to specify handlers using a full range of CSS3 selectors (and then some). jQuery当然具有livedelegate函数,它允许你使用全范围的CSS3选择器(然后是一些)来指定处理程序。

For example, here's the equivalent code using jQuery (except I'm sure jQuery handles edge cases the off-the-cuff raw version above doesn't): 例如,这里是使用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);

Live copy 实时复制

You might want to create a helper function like this: 您可能想要创建一个这样的辅助函数:

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

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

Your code contains a typo: 您的代码包含拼写错误:

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

so 所以

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

works. 作品。 Cheers! 干杯!

[ edit ] based on comment: and this should run and return the function in one go: [ edit ]基于评论:这应该运行并一次性返回函数:

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

Even simpler with ES6: 使用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"

Try to do like that: 试着这样做:

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

If you want to create a function and execute immediately - 如果你想创建一个函数并立即执行 -

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

For my application I went for the easiest way.对于我的应用程序,我选择了最简单的方法。 I just need to fire a function immediately when the page load and use it again also in several other code sections.我只需要在页面加载时立即触发 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.

相关问题 强制 javascript 超时函数立即执行 - force a javascript timeout function to execute immediately 在JavaScript中,为什么我不能立即调用函数声明? - In JavaScript, why can't I immediately invoke function declarations? 如何在AppleScript中执行JavaScript函数? - How can I execute JavaScript function in AppleScript? webextension 弹出窗口可以在打开后立即执行 javascript(即没有用户交互)吗? - Can a webextension popup execute javascript immediately after opening (i.e. without user interaction)? 当我将其名称作为字符串时执行 JavaScript 函数 - 不工作 - Execute a JavaScript function when I have its name as a string - Not working 当我将其名称作为字符串时如何执行 JavaScript function - How to execute a JavaScript function when I have its name as a string 加载后如何立即在动态加载的javascript上执行功能? - How to execute function on dynamically loaded javascript immediately after loading? 如何在 JavaScript 中的 onclick 之后立即执行 function? - How to make a function execute immediately after onclick in JavaScript? 如何创建指向页面的链接并强制它立即执行 javascript - How do I create a link to a page and force it to immediately execute a javascript 如何使用变量名执行函数? - How can I execute a function using a variable name?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM