自执行块中的Javascript函数不可访问。为什么?

时间:2015-10-19 02:57:03

标签: javascript html function scope

我有一个带有一些可拖动图像的简单index.html文件。我的JS文件如下所示:

    function drop(ev){
      ev.preventDefault();
      var data = ev.dataTransfer.getData('text');
      ev.target.appendChild(document.getElementById(data));
    }

    function drag(ev){
      ev.dataTransfer.setData('text',ev.target.id);
    }

完美无缺。但是,正如我所知,在自执行的块中编写代码是一种很好的做法。

所以,我移动了我的两个功能:

    (function(){

      function drop(ev){
        ev.preventDefault();
        var data = ev.dataTransfer.getData('text');
        ev.target.appendChild(document.getElementById(data));
      }

      function drag(ev){
        ev.dataTransfer.setData('text',ev.target.id);
      }

    })();

现在,当拖动图像时,功能似乎是“未定义的”。他们可能是新手问题但是:

  • 我可以将我的功能保留在块范围内,并仍在HTML <div id="div0" ondrop="drop(event)">...</div>上使用它们吗?

  • 如果没有,为什么?

3 个答案:

答案 0 :(得分:2)

将材料封入IIFE的重点是隔离它们,而不是用不必要的污染全球环境。例如,

var counter = (function() {
  var current = 0;
  function getCurrentAndIncrement() {
    return current++;
  };
  return getCurrentAndIncrement;
})();

counter()
// 0
counter()
// 1
current
// ReferenceError: current is not defined

我们隐藏应该私有的内容,并公开应该公开的内容。

你隐瞒了一切 - 然后它无法进入的事实不应该是一个惊喜。

最后,<div id="div0" ondrop="drop(event)">...</div>是一种不好的做法。如果有点复杂的话,来自JavaScript的绑定事件监听器要好得多。做到这一点:

<div id="div0">...</div>

然后在JavaScript中,

var div0 = document.getElementById('div0');
div0.addEventListener('drop', myHandler);
事实上,这可以填入IIFE。无论您从HTML中引用什么(如在drop函数中),都需要在全局范围内,否则浏览器将无法找到它。

答案 1 :(得分:1)

答案是范围。函数中定义的变量和函数只能在该函数中访问。在您的第一个示例中,您将全局定义它们;在你的第二个例子中,它们在一个函数中。

  

我可以将我的功能保留在块范围内,并仍在HTML <div id="div0" ondrop="drop(event)">...</div>上使用它们吗?

要使用老式onxyz属性处理程序中的函数,它们必须是 globals 。您可以通过将函数分配给全局对象上的属性来使函数成为全局函数,您可以在浏览器上以window访问它们:

(function() {

    function drop(ev) {
        ev.preventDefault();
        var data = ev.dataTransfer.getData('text');
        ev.target.appendChild(document.getElementById(data));
    }

    function drag(ev) {
        ev.dataTransfer.setData('text', ev.target.id);
    }

    window.drop = drop;
    window.drag = drag;

})();

...但理想情况下,创建全局变量更好 ;全局命名空间令人难以置信地拥挤,增加它只是要求冲突。相反,请使用现代事件处理(addEventListenerattachEvent)而不是onxyz属性。

答案 2 :(得分:0)

内部功能不会被执行。这里有封闭的美丽使js对象私密和放大上市 。此代码可能符合您的目的

var demoFunction =(function(){
    function _drop(ev){
        alert("Helo");
          _drag();
      }
    function _drag(ev){
       alert("Hello1");
      }
    _drop();

   return{
         drop :_drop,
         drag:_drag    
    }
})();

您也可以通过demoFunction.drop&amp; amp;来调用此drop并从其他函数拖动。等等。希望这对你有帮助

jsfiddle