2012-05-26 2 views
4

У меня возникла довольно интересная проблема. В приведенном ниже коде создается массив, который при регистрации регистрирует значение [undefined × 1]. Согласно this answer, это означает, что массив имеет униализированные индексы - в этом случае только один. Однако, поскольку я использую только array.push(), чтобы избежать такого рода проблем, я потерял. Насколько мне известно, причиной этой проблемы может быть присвоение индекса хотя бы одним индексом, большим, чем другие инициализированные индексы. Во всяком случае, вот код:Единичные переменные в массиве при использовании только Array.push?

function Thing(params) { 
    var that = this; 

    this.OtherObject = function OtherObject(param) { 
     this.param = param; 
    } 

    this.Foo = function Foo() { 
     this.bar = []; 

     this.add = function(item) { 
      if (this.bar.length != 0) { 
       for (var i = 0, len = this.bar.length; i < len; i++) { 
        if (this.bar[i].param <= item.param) { 
         this.bar.splice(i, 0, item); 
        } 
       } 
      } else { 
       this.bar[0] = item; 
       console.log(this.bar); 
      } 
     } 

     this.pop = function() { 
      return this.bar.pop(); 
     } 

     this.length = function() { 
      return this.bar.length; 
     } 
    } 

    this.someFunc = function() { 
     var myThing = new that.Foo(); 
     myThing.add(new that.OtherObject(3)); 

     while (myThing.length() > 0) { 
      var someVar = myThing.pop(); 
     } 
    } 
} 

var myThing = new Thing({ 
    myParam: "someValue" 
}); 

myThing.someFunc(); 
​ 

Я создал тестовый пример, чтобы увидеть, если я мог бы локализовать проблему, но я в конечном итоге повторно набрав 95% мой код, пока я снова не столкнулся с вопросом, который появляется чтобы быть связанным с моим использованием myThing.pop(). Вы можете найти скрипку here, которая демонстрирует проблему.

Итак ... любые идеи относительно того, что может быть причиной этого? Это на самом деле проблема с тем, как я вложил свои объекты? (что я сделал по шаблону, приведенному мне в this answer, на предыдущий вопрос).

В случае, если вам интересно, что я мог бы здесь сделать, я рассматриваю внешний объект как своего рода пространство имен, которое я делаю, чтобы избежать загромождения глобального пространства имен (это в конечном итоге будет библиотеку путей, если я получу свой совместный акт здесь). Объект Foo предназначен для своего рода упорядоченного списка, так что я могу получить ближайший узел (тот, который имеет самое низкое свойство param) на pop() в стеке.

+0

В каком браузере вы тестируете это? Вы пробовали других? – loganfsmyth

+0

Возможно, вы захотите дважды проверить, что это значение действительно неверно.Это выглядело просто пустым для меня, что все еще странно, пока я не вспомнил, что Chrome динамически обновляет некоторый вывод console.log. Поэтому, поскольку вы позже выходили, он обновлял напечатанный массив, отображаемый как пустой. Или что-то. Если вы выполните console.log (this.bar.toString()), вы видите элемент? – loganfsmyth

ответ

2

Существует только что-то, что очень странно с функцией console.log в Google Chrome. Другие браузеры, похоже, ведут себя так, как вы ожидали. Это одна из странных вещей, которые я видел: если вы добавите вызов alert после lne, который вызывает console.log, в консоли будет отображаться другой вывод.

console.log(this.bar); 
alert(this.bar); 

// [> OtherObject] 

Если вы удалите alert, как вы уже видели, консоль будет выводить

// [undefined × 1] 

Такого рода вещи либо из-за некоторые условия гонки или каким-то побочный эффект, что функция alert является причиной , Вот моя теория о том, что происходит за кулисами:

  • console.log функция фактически не войти значения в консоли, пока не будет какой-то привал в коде, а затем он записывает все сообщения в очереди. Очередь содержит ссылки на сообщения, которые должны быть зарегистрированы.
  • Первый элемент в this.bar уничтожается, когда вы набираете массив. Регистратор, если не будет какого-либо прерывания, отобразит сообщение после уничтожения ссылочного значения. Таким образом, он отображает
  • Вызов alert вызывает остановку в коде, чтобы консоль могла зарегистрировать сообщение до того, как указанное значение будет стерто.

Я все еще не полностью уверен, если это действительно то, что происходит, но это, кажется, быть somwhat разумным. Я сделаю еще несколько тестов, чтобы проверить правильность моей теории.

Смежные вопросы