2015-07-01 2 views
0

Сегодня я столкнулся с очень интересной проблемой, которую многие из вас могут найти элементарно, но поскольку я просто изучаю использование jQuery, мне интересно знать, как это работает.область действия «this» в функции jQuery

У меня есть два массива, и я повторяю элементы массива. Один массив - arrAllDetailsConstantData, а другой - arrAllDetails. Я хочу сравнить с помощью arrAllDetailsConstantData и обновление с помощью arrAllDetails.

Я использую вложенные петли. Но происходит то, что при обновлении массива arrAllDetails, массив arrAllDetailsConstantData также обновляется. Я предполагаю, что это как-то связано с охватом родителя (хотя я просто догадываюсь). Не могли бы вы мне помочь?

Вот мой код:

$.each(privateVariables.arrAllDetailsConstantData, function() { 
    if (this.AssociationId == value && this.uniqueChargeAttr == uniqueChargeAttr) { 

     if (this.Units == $("#txtUnits").val() && 
      this.Modifier1 == $("#txtModifier1").val() && 
      this.Modifier2 == $("#txtModifier2").val() && 
      this.Modifier3 == $("#txtModifier3").val() && 
      this.Modifier4 == $("#txtModifier4").val() && 
      this.DxOption == $("#ddlDxOption").val() && 
      this.DxCode1 == $("#txtDx1").val() && 
      this.DxCode2 == $("#txtDx2").val() && 
      this.DxCode3 == $("#txtDx3").val() && 
      this.DxCode4 == $("#txtDx4").val()) { 

     } else { 
      $.each(arrAllDetails, function() { 
       if (this.AssociationId == value && this.uniqueChargeAttr == uniqueChargeAttr) { 
        this.ActionType = "M"; 
        this.CptName = $("#lblCptDesc").text(); 
        this.CptDesc = $("#lblCptDesc").text(); 
        this.Units = $("#txtUnits").val(); 
        this.Modifier1 = $("#txtModifier1").val(); 
        this.Modifier2 = $("#txtModifier2").val(); 
        this.Modifier3 = $("#txtModifier3").val(); 
        this.Modifier4 = $("#txtModifier4").val(); 
        this.DxOption = $("#ddlDxOption").val(); 
        this.DxCode1 = $("#txtDx1").val(); 
        this.DxCode2 = $("#txtDx2").val(); 
        this.DxCode3 = $("#txtDx3").val(); 
        this.DxCode4 = $("#txtDx4").val(); 

        privateVariables.arrActionData.push(this); 

       } 
      }); 
     } 
    } 
}); 

// test code ends 
+1

_this_ внутри функции обратного вызова JQuery относится к элементу итерированного – Grundy

+0

Но тогда почему оба массива становятся обновляться .. Только arrAllDetails должен быть обновлен в этом случае. –

+1

'privateVariables.arrActionData.push (this);' здесь вы добавляете элемент из 'arrAllDetails' в' privateVariables.arrActionData', поэтому при обновлении этого элемента значения изменяются во всех массивах, потому что в массиве сохранена только ссылка на тот же объект – Grundy

ответ

1
  • Во-первых, номерjQuery относится к вызывающему элементу.

В $.each, это относится к итерированного элемента.

Таким образом, в первом цикле: $.each(privateVariables.arrAllDetailsConstantData, function() {});, this будет в настоящее время зацикливания элемента вашего arrAllDetailsConstantData массива.

Во втором цикле, this будет в настоящее время зацикливания элемента вашего arrAllDetails массива.

  • Во-вторых, нам нужен код создания массивов.

Не забывайте, что на многих языках, что если вы используете этот arrAllDetailsConstantData = arrAllDetails, ссылка указатель на те два объекта указывают на тот же диапазон памяти. В этом случае используйте arrAllDetailsConstantData = arrAllDetails.slice(); от Array.prototype.slice.

+0

Будет ли использовать .slice, чтобы массив указывал на другое место в памяти? –

+2

Функция '.slice()' prototype создаст «клон» вашего массива, но они будут ** разными ** объектами да –

+0

Так массивы заполняются. arrAllDetails = response.aaData; privateVariables.arrAllDetailsConstantData = response.aaData; –

0

за рамки «это» вы можете проверить JQuery and 'this' object

Что касается вашего кода: Вам нужно добавить, как вы создали два массива в первом место.

Основываясь на вашем коде, они, похоже, создаются с использованием тех же элементов (поэтому arrDetails представляется подмножеством объектов в arrAllDetails). Что-то в пути

$.each(arrDetails, function() {arrAllDetails.push(this); }); 

или просто assinging:

arrDetails = arrAllDetails; 

Если это так, то объект в пределах массивов, на самом деле то же самое. Поэтому редактирование элемента в одном массиве также отредактирует его в другом массиве (они указывают на один и тот же объект в памяти).

Я не уверен, что вы пытаетесь выполнить, но если вы хотите, чтобы объекты были разными, вам нужно клонировать записи, чтобы они были отдельными объектами, а не просто использовали их.

Кроме того, вы понимаете это из-за этого (оно относится к ближайшей области) правильно, но переопределены другими проблемами.

+0

Ответ, который вы связали с jQuery и объектом «this», говорит о обработчиках событий jQuery, содержащих элемент DOM. Это не очень важно здесь ... в функции 'each' jQuery,' this' просто ссылается на текущий элемент массива. –

+0

Да, U r справа. Оба массива заполняются одним и тем же источником. Я должен поддерживать два массива для обнаружения любых изменений, внесенных в поля пользовательского интерфейса во время выполнения. Любые предложения, как я могу избежать обновления массива arrAllDetailsConstantData –

+0

Вы можете «клонировать» массив, используя: http://api.jquery.com/clone/, который создаст полный отдельный набор. – Niko

0

В Javascript this относится к владельцу функции-исполнения. Не всегда легко узнать, что на самом деле является владельцем. С областью определения HTML-элементов, this обычно относится к самим элементам. Внутри итерации (например, $.each(data, function)) this относится к элементу, который повторяется.

Вы используете this в разных контекстах. Каждый раз в другой итерации.

$.each(privateVariables.arrAllDetailsConstantData, function() { 
    if (this.AssociationId == value && this.uniqueChargeAttr == uniqueChargeAttr) { 
     //in this context: "this" refers to the currently selected 
     //item of the iteration over: 
     // privateVariables.arrAllDetailsConstantData 
    } else { 
     $.each(arrAllDetails, function() { 
      // in this context: "this" refers to the selected item 
      // of the iteration over "arrAllDetails" 
     }); 
    } 
}); 

Вы можете сохранить контекст при вводе итерацию путем связывания this локальной переменной.

$.each(privateVariables.arrAllDetailsConstantData, function() { 
    if (this.AssociationId == value && this.uniqueChargeAttr == uniqueChargeAttr) { 
     // this refers to an item from privateVariables.arrAllDetailsConstantData 
    } else { 
     var context = this; 
     $.each(arrAllDetails, function() { 
      // context refers to an item from privateVariables.arrAllDetailsConstantData 
      // so: use 
      context.AssociationId 
      // instead of 
      this.AssociationId 
     }); 
    } 
}); 
Смежные вопросы