JS / Javascript с использованием .push или .unshift предназначен для отслеживания истории переменной

#javascript #arrays #json

#javascript #массивы #json

Вопрос:

Я работаю над программой для чтения книг. У меня есть переменная currentPostition, которая, как следует из ее названия, всегда знает, в какой части книги находится пользователь. Я пытаюсь создать историю местоположения пользователей, чтобы я мог добавить кнопку «Назад», как в веб-браузере. Итак, в настройках у меня есть:

 currentPostition;  //this is a json object with book,chapter,page stored in it.
history = [];          //array of json objects
  

Затем, позже, когда пользователь выполняет навигацию (существует несколько разных типов навигации):

 history.push(currentPostition);  //save in history before updating currpos

//put new values in currentPosition
currentPostition.book = foo;
currentPostition.chapter = foo;
currentPostition.page = foo;
  

Пока все хорошо, не так ли? Ну, проблема такая. Мой массив истории увеличивается в длину, как и следовало ожидать. НО каждая запись в массиве истории будет такой же, как и последний объект, помещенный в массив. IE:

 for (x=0;v<history.lenght;x  ){
   document.write(history[x].book "," history[x].chapter "," history[x].page "<br />");
}
  

приведет к выводу чего-то вроде

3RD Bookposition,3RD chapterposition,3RD Pageposition 3RD bookposition,3RD chapterposition,3RD pageposition 3RD bookposition,3RD chapterposition,3RD pageposition

Итак, я в тупике, потому что я ожидаю вывода типа:

1ST Bookposition,1stChapterPosition,1stPagePosition 2ndBookPosition,2ndChapterPosition,2ndPagePosition 3RD Bookposition,3RD chapterposition,3RD Pageposition

Что я делаю не так? К вашему сведению, я пробовал unshift и history[history.length] также и в сети те же результаты.

Заранее спасибо, Джев

Ответ №1:

В основном все в JS передается по ссылке. Таким образом, вы добавляете в массив только ссылку на currentPostition. Вам нужно назначить новый пустой объект, прежде чем использовать currentPostition в другой раз:

 currentPostition = {};
  

Ответ №2:

Проблема в том, что вы помещаете тот же экземпляр вашего объекта currentPosition в свой массив истории. В результате вы получите несколько указателей на один и тот же экземпляр currentPosition.

Чтобы избежать этой проблемы, вам нужно использовать новый экземпляр currentPosition либо с помощью ключевого слова new, если у вас есть функция-конструктор, либо просто скопировав объект в другой, как это делается $.extend({},currentPosition) с помощью jQuery.

Надеюсь, это поможет.

Редактировать: Вы можете создать свою собственную функцию extends, что-то вроде этого:

 function extends(destObject,srcObject){
  for(var i in srcObject){
    destObject[i] = srcObject[i];
  }
}
  

Это действительно простая версия, вы можете найти немного более сложную версию, которая будет рекурсивно клонировать ваш объект, но я полагаю, что меня может быть достаточно для вашего вопроса, поэтому было бы:

 var oldPos = extends({},currentPosition);
history.push(oldPos);
  

Комментарии:

1. У меня нет доступа к jquery. Как еще я могу скопировать объект в другой без jquery?

2. вы можете объявить свою собственную функцию extends, см. Редактирование предыдущего ответа, который я сделал