我可以命名一个javascript函数并立即执行它吗?

时间:2022-03-23 07:32:33

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. Since they have to be attached initially as well (duh), they're in a nice function to be DRY.

重新添加事件是必要的,因为DOM已经更改,所以以前附加的事件将消失。因为它们一开始也要连接(对了),所以它们的功能很好,可以保持干燥。

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函数并立即调用它,这样看起来就不会那么业余了。

Both following respond with a syntax error:

后面两个都有语法错误:

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

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

Any takers?

什么人吗?

7 个解决方案

#1


89  

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. A function declaration:

在JavaScript中定义函数有两种方法。一个函数声明:

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.

因此,为了命名你的函数并立即调用它,你需要定义一个局部变量,将你的函数赋值为表达式,然后调用它。

#2


5  

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。目标(或事件。在IE上的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:

这里有一个不使用任何辅助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. Now, you probably root this in something more targeted than document.body, but you get the idea. 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. 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).

现代的JavaScript库,如jQuery、Prototype、YUI、Closure或其他一些库,应该提供事件授权特性,以消除浏览器的差异,并干净地处理边缘情况。jQuery当然会使用它的live和delegate功能,它允许您使用完整的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

生活本

#3


5  

There is a good shorthand to this (not needing to declare any variables bar the assignment of the function):

这里有一个很好的简写(除了函数的赋值之外,不需要声明任何变量):

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

#4


4  

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:

[编辑]基于评论:这应该一次运行并返回函数:

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

#5


2  

You might want to create a helper function like this:

您可能想要创建这样的助手函数:

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

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

#6


0  

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

#7


0  

Try to do like that:

试着这样做:

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

#1


89  

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. A function declaration:

在JavaScript中定义函数有两种方法。一个函数声明:

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.

因此,为了命名你的函数并立即调用它,你需要定义一个局部变量,将你的函数赋值为表达式,然后调用它。

#2


5  

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。目标(或事件。在IE上的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:

这里有一个不使用任何辅助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. Now, you probably root this in something more targeted than document.body, but you get the idea. 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. 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).

现代的JavaScript库,如jQuery、Prototype、YUI、Closure或其他一些库,应该提供事件授权特性,以消除浏览器的差异,并干净地处理边缘情况。jQuery当然会使用它的live和delegate功能,它允许您使用完整的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

生活本

#3


5  

There is a good shorthand to this (not needing to declare any variables bar the assignment of the function):

这里有一个很好的简写(除了函数的赋值之外,不需要声明任何变量):

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

#4


4  

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:

[编辑]基于评论:这应该一次运行并返回函数:

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

#5


2  

You might want to create a helper function like this:

您可能想要创建这样的助手函数:

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

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

#6


0  

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

#7


0  

Try to do like that:

试着这样做:

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