从addEventListener调用函数

时间:2016-02-11 13:00:44

标签: javascript javascript-events

我有一个表单,我在表单中添加addEventListener()。我想在addEventListener()内调用一个函数,但我在函数调用时得到一个Uncaught TypeError

代码1

$(document).ready(function(){
  function uploadFile(){
      alert("comes here");
  }

  uploadForm.addEventListener('submit', function(e) {
      var uploadFile = document.getElementById('upload-file').files;
      e.preventDefault();
      uploadFile();
  });
});

但如果我将上面的代码更改为

代码2

$(document).ready(function(){
  var test = function uploadFile(){
      alert("comes here");
  }

  uploadForm.addEventListener('submit', function(e) {
      var uploadFile = document.getElementById('upload-file').files;
      e.preventDefault();
      test();
  });
});

有效。我想知道为什么。它可能与范围有关。但是根据我所知,我认为函数(uploadFile())和函数引用(test)具有相同的范围。

我是一名自学成才的程序员,所以我不知道谷歌应该知道为什么会这样。我得到的最近的是thisfunction naming

作为答案,我只是在寻找一些我可以谷歌来理解为什么会发生这种情况的术语。

2 个答案:

答案 0 :(得分:3)

您已使用名为uploadFile的变量覆盖了函数名uploadFile,它只是名称冲突

$(document).ready(function(){
  function uploadFile(){ //uploadFile function declaration
      alert("comes here");
  }

  uploadForm.addEventListener('submit', function(e) {
      //function uploadFile already declared, and now you are using var here
      var uploadFile = document.getElementById('upload-file').files;
      e.preventDefault();
      uploadFile();
  });
});

简单的名称更改将有助于

$(document).ready(function(){
  function uploadFile2(){ //NOTICE NAME
      alert("comes here");
  }

  uploadForm.addEventListener('submit', function(e) {
      var uploadFile = document.getElementById('upload-file').files;
      e.preventDefault();
      uploadFile2(); //NOTICE NAME
  });
});

在第二个示例中,一切正常,因为您有函数名test,它不会与uploadFile变量冲突

同时结帐@JuanMendes回答,因为它解释了问题的原因,对知识库非常有用

答案 1 :(得分:2)

Medet是正确的,var uploadFile会覆盖外部的function uploadFile()。不过,我想补充一些额外的解释,说明为什么var test = function uploadFile()与本地var uploadFile没有真正冲突

原因是当您为变量分配函数时,您有一个函数表达式。通常它们是匿名的,但您已创建了一个命名函数表达式。在这种情况下,函数的名称仅在uploadFile函数本身内有效(可用于递归),这就是它不与内部函数中定义的uploadFile冲突的原因。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/function#Named_function_expression

  

如果要引用函数体内的当前函数,则需要创建一个命名函数表达式。这个名称只对函数体(范围)是本地的。这也避免了使用非标准的arguments.callee属性。