函数参数求值为undefined

时间:2018-03-25 02:12:10

标签: javascript html

动态创建select类型的元素时,设置onclick方法时会出现两个问题:

  1. 无法简单地将onclick设置为element.onclick="updateInput(this.articleIndex)";
  2. 这会产生最终的HTML标记,其中根本不显示onclick

    当由e.setAttribute("onclick","updateInput(this.articleIndex)");设置时,它会出现在最终的HTML中。并调用updateInput方法。

    1. 但是功能似乎被打破了,因为参数总是评估为undefined
    2. 这是我的问题的一个简单例子:

      var selectElem = document.createElement("select");
      selElem.id="articleSelector_"+this.articleIndex; 
      console.log("the index of the article is " + this.articleIndex);
      selElem.setAttribute("onclick","updateInput(this.articleIndex);");
      //selElem.onclick="updateInput(this.articleIndex)"; //this does not work
      

      日志显示正确的数字。在updateInput方法中,参数的值为undefined,而不是之前在日志中显示的数字。

3 个答案:

答案 0 :(得分:2)

尝试使用纯Javascript附加处理程序,而不使用HTML,没有onclick = "...(这与eval一样糟糕)。

脚本中的this是指函数的调用上下文 - 它是什么?

你可能想要:

element.addEventListener('click', () => {
  updateInput(this.articleIndex);
});

(箭头函数保留其周围范围的this

答案 1 :(得分:2)

  

用element.onclick =" updateInput(this.articleIndex)";

简单地设置onclick是不可能的。

该代码的作用是将字符串"updateInput(this.articleIndex)"分配给onclick,这是没有意义的,当然也不是你想要的。

即使您删除了引号:

element.onclick = updateInput(this.articleIndex);

它仍然不正确,因为它会将updateInput()函数的结果分配给onclick,而这又不是您想要的。

您需要为onclick指定一个函数名称,如下所示:

element.onclick = updateInput;

但是,这并不允许您根据需要传递参数。为此,您需要使用匿名函数:

element.onclick = function() {
    updateInput(this.articleIndex)
};
  

当由e.setAttribute(" onclick"," updateInput(this.articleIndex)");设置时,它确实出现在最终的HTML中。并调用updateInput方法。

这是有效的,因为它设置属性onclick并且它是字符串类型,所以一切都是正确的。它相当于使用上面的匿名函数。唯一的区别是this,在这种情况下是指元素本身,而在上面的代码中,它取决于代码出现的上下文。这就是为什么在这种情况下参数始终求值为undefined因为select元素没有articleIndex属性。

答案 2 :(得分:1)

问题是当单击该元素时上下文this的值,当前不再提供上下文this

您有两种方法可以解决此问题:

  • 您可以使用函数addEventListener绑定事件单击,并将函数/处理程序与所需的上下文绑定this

函数bind将特定上下文绑定到函数。

selElem.addEventListener('click', updateInput.bind(this));

function updateInput() {
    console.log(this.articleIndex);
}
  • 由于您需要特定值,因此您可以使用数据属性。这样,您就不必担心上下文this
selElem.dataset.articleIndex = this.articleIndex;
selElem.addEventListener('click', function() {
  updateInput(this.dataset.articleIndex); // Here you can get that value.
});