没有自我调用功能的javascript代码

时间:2015-08-03 09:26:35

标签: javascript

以下代码工作正常。我想要的是做同样的事情,但没有任何自我调用功能

<html>
<body>
<input type='button' value='click' onclick="addLinks()">
</body>
</html>

<script type="text/javascript">
function addLinks ()
{ 
 for (var i=0, link; i<5; i++)
  { 
    link = document.createElement("a"); 
    link.innerHTML = "Link " + i;
    link.onclick = (function (x) //self invoking function
      {
        return function()
           { 
               alert(x); 
           };
      })(i);
document.body.appendChild(link); } }
</script>

1 个答案:

答案 0 :(得分:3)

您可以通过拆分来避免创建一次性IIFE:

function addLinks() {
    for (var i = 0, link; i < 5; i++) {
        link = document.createElement("a");
        link.innerHTML = "Link " + i;
        link.onclick = buildHandler(i);
        document.body.appendChild(link);
    }

    function buildHandler(x) {
        return function() {
            alert(x);
        };
    }
}

但我们可以做得更好:如何为所有链接使用一个处理函数?

function addLinks() {
    for (var i = 0, link; i < 5; i++) {
        link = document.createElement("a");
        link.innerHTML = "Link " + i;
        link.setAttribute("data-x", i);
        link.onclick = handler;
        document.body.appendChild(link);
    }

    function handler() {
        alert(this.getAttribute("data-x"));
    }
}

当然,这只适用于你可以合理地转换为字符串的字符串或事物。

如果你对expando属性没问题,我们可以超越字符串:

function addLinks() {
    for (var i = 0, link; i < 5; i++) {
        link = document.createElement("a");
        link.innerHTML = "Link " + i;
        link.__x__ = i;
        link.onclick = handler;
        document.body.appendChild(link);
    }

    function handler() {
        alert(this.__x__);
    }
}

jQuery使用expando来完成它的一些功能,因此我们知道它们在跨浏览器时运行良好。如果你搜索你也会找到反对他们的论据。我回避了。

或者我们可以使用Function#bind

function addLinks() {
    for (var i = 0, link; i < 5; i++) {
        link = document.createElement("a");
        link.innerHTML = "Link " + i;
        link.onclick = handler.bind(link, i);
        document.body.appendChild(link);
    }

    function handler(x) {
        alert(x);
    }
}

附注:作为一般做法,我主张在过时的IE上使用addEventListenerattachEvent而不是onclick。例如。对于最后一个例子:

link.addEventListener("click", handler.bind(link, i), false);