Javascript 'this' 作为参数

Javascript 'this' as parameter

本文关键字:参数 this Javascript      更新时间:2023-09-26

我正在尝试将值从"FROM"字段复制到"TO"字段中。我的第一次尝试是这样的:

function updateToField(toField,fromField)
{
    toField.value = fromField.value}
}
function verifyFromToFields()
{
var inputs = getElementsByTagName("input");
for (var j = 0; j < inputs.length; j++)
{
    if (inputs[j].name.indexOf('FROM') != -1 && if (inputs[j+1].name.indexOf('TO') != -1)
        {
            var fromField = inputs[j];
            var toField   = inputs[j+1];
            fromField.onchange = function(){updateToField(toField,fromField)};
        }
}

该网站有几个 FROM-TO 对,这似乎仅适用于"inputs"数组中的最后一对。

然后我试了这个:

function updateToField(toField,fromField)
{
    toField.value = fromField.value}
}
function verifyFromToFields()
{
var inputs = getElementsByTagName("input");
for (var j = 0; j < inputs.length; j++)
{
    if (inputs[j].name.indexOf('FROM') != -1 && if (inputs[j+1].name.indexOf('TO') != -1)
        {
            var fromField = inputs[j];
            var toField   = inputs[j+1];
            fromField.onchange = function(){updateToField(toField,this)};
        }
 }

这样,当修改页面中的任何 FROM 字段时,它将被复制到页面上的最后一个 TO 字段。我认为这是我读到的关于参数作为值或参考的问题之一,但我无法弄清楚。此外,这是一个非常简化的代码版本,我实际上用 getElementsByClass 函数填充输入列表,并且必须搜索子节点。有没有人知道发生了什么?

那个结束,我不认为它意味着你认为它的意思。

这里这一行:

     fromField.onchange = function(){updateToField(toField,this)};

表示"分配给onchange一个函数,该函数将该字段的内容分配给更改时的任何toField

由于您只有一个变量toField因此所有可更改字段都将分配给它。

这将起作用:

var setOnChange = function(fromField, toField) {    
   fromField.onchange = function(){updateToField(toField,this)};
};
for (var j = 0; j < inputs.length; j++)
{
    if (inputs[j].name.indexOf('FROM') != -1 && if (inputs[j+1].name.indexOf('TO') != -1)
        {
            setOnChange(inputs[j], inputs[j+1]);
        }
 }

编辑:艾萨克可能对这个问题有更好的解释(尽管我不太喜欢他的解决方案)。

这是因为

闭包的工作方式。当您分配onchange函数时,您(为每个循环)创建一个调用 updateToField 的新匿名函数,但toFieldthis参数(或您传递的任何其他参数)的值不会绑定到"当前"循环,而是将参数绑定到循环的最后一个值(这就是为什么只使用最后一个"TO")。

不要onchange属性分配一个新函数,如果您在具有该函数的环境中运行,请尝试调用该Function.bind,如果没有该函数,请尝试编写该函数。

以下是bind的文档

所以你可以这样:

fromField.onchange = updateToField.bind(this, fromField, toField);

或者你可以使用马尔沃利奥写的另一种方法。

这个问题实际上与范围有关。正在发生的事情是,您的函数(您分配给onchange的函数)正在捕获toFieldfromField变量,并且它们的值不断变化。我知道看起来您每次都通过循环重新声明它们,但这不是 JS 的工作方式;通过循环的连续行程共享一个范围,因此每次fromField都是相同的变量,您只需在每次迭代中为其分配一个新值。所以最后,你的所有函数都引用同一个fromField变量。而fromField变量自然包含您为其分配的最后一个值。

因此,当你最终调用所有这些函数时,它们都做同样的事情,因为它们的所有fromField(以及,按照相同的逻辑,toField s)都是同一个变量。因此,这就解释了为什么只有最后的输入有效;它们是运行函数时fromFieldtoField包含的内容。

您可以通过引入中间函数来解决此问题,因为函数确实会创建新的作用域。这样,每次通过循环,您都会获得全新的变量。

function updateToField(toField,fromField)
{
   toField.value = fromField.value;
}
function verifyFromToFields()
{
  var inputs = getElementsByTagName("input");
  for (var j = 0; j < inputs.length; j++)
  {
    function(){
      if (inputs[j].name.indexOf('FROM') != -1 && if (inputs[j+1].name.indexOf('TO') != -1)
      {
          var fromField = inputs[j];
          var toField   = inputs[j+1];
          fromField.onchange = function(){updateToField(toField,fromField)};
      }
   }();
}