Javascript: console.log(arr.length) говорит, что длина равна n, console.log(arr) говорит, что длина равна n-1. Во втором случае не будет отображаться последний элемент

Первая строка напечатает, скажем, 10, а вторая напечатает на 1 меньше:

console.log("ds length: " + ds.length);  // Prints, say, 10
console.log(ds); // Prints all but last element and says length is one less.

Некоторые важные части моего кода, все в единственном AS:

FindPath: function(oX, oY, dX, dY) { // origin, destination
        var heap = AS.Heap();

        var g = AS.Grid; // AS.Grid is declared, in AS, as: Grid: new Array(),

        var node;

        var cn = g[oX][oY]; // current node
        var dn = g[dX][dY]; // destination node

        heap.push(cn);

        cn.CoorType = AS.CoorType.VISITED;

        while (heap.length > 0) {
            cn = heap.pop();

            if (cn === dn) {
                var ds = new Array(); // direction set (instructions)
                var pn;// parent node;

                do {
                    pn = cn.Parent;
                    ds.push({
                        Dir: cn.Y - pn.Y !== 0 ? cn.Y - pn.Y < 0 ? AS.Direction.UP : AS.Direction.DOWN : cn.X - pn.X > 0 ? AS.Direction.RIGHT : AS.Direction.LEFT,
                        Node: cn});
                    cn = pn;
                } while (pn.Parent);

                console.log("ds length: " + ds.length);
                console.log(ds);

                AS.CleanUp();
                return ds;
            }

                    // Bellow, I'm not using functions 'cause occasionally, when FindPath() is called multiple times in a large area within a few milliseconds, it will get laggy. I removed the use of functions to increase performance.
            node = g[cn.X+1][cn.Y];
            if (node.CoorType === AS.CoorType.NOTHING) {
                node.CoorType = AS.CoorType.VISITED;
                node.Parent = cn;
                node.Score = ((Math.abs(node.X - oX) + Math.abs(node.Y - oY)) * AS.SMALL_ADVANTAGE + Math.abs(node.X - dX) + Math.abs(node.Y - dY)) +
                        Math.abs((node.X - dX) * (oY - dY) - (node.Y - dY) * (oX - dX)) * 0.0001;
                heap.Sink(node);
            }
            node = g[cn.X][cn.Y+1];
            if (node.CoorType === AS.CoorType.NOTHING) {
                node.CoorType = AS.CoorType.VISITED;
                node.Parent = cn;
                node.Score = ((Math.abs(node.X - oX) + Math.abs(node.Y - oY)) * AS.SMALL_ADVANTAGE + Math.abs(node.X - dX) + Math.abs(node.Y - dY)) +
                        Math.abs((node.X - dX) * (oY - dY) - (node.Y - dY) * (oX - dX)) * 0.0001;
                heap.Sink(node);
            }
            node = g[cn.X-1][cn.Y];
            if (node.CoorType === AS.CoorType.NOTHING) {
                node.CoorType = AS.CoorType.VISITED;
                node.Parent = cn;
                node.Score = ((Math.abs(node.X - oX) + Math.abs(node.Y - oY)) * AS.SMALL_ADVANTAGE + Math.abs(node.X - dX) + Math.abs(node.Y - dY)) +
                        Math.abs((node.X - dX) * (oY - dY) - (node.Y - dY) * (oX - dX)) * 0.0001;
                heap.Sink(node);
            }
            node = g[cn.X][cn.Y-1];
            if (node.CoorType === AS.CoorType.NOTHING) {
                node.CoorType = AS.CoorType.VISITED;
                node.Parent = cn;
                node.Score = ((Math.abs(node.X - oX) + Math.abs(node.Y - oY)) * AS.SMALL_ADVANTAGE + Math.abs(node.X - dX) + Math.abs(node.Y - dY)) +
                        Math.abs((node.X - dX) * (oY - dY) - (node.Y - dY) * (oX - dX)) * 0.0001;
                heap.Sink(node);
            }
        }

        AS.CleanUp();
        return heap; // No path found
    },

Heap: function() {
    var heap = new Array();

    heap.Sink = function(node) {
        var i = this.length-1;

        while (i > 0 && this[i].Score < node.Score) i--;

        this.splice(i, 0, node);
    };

    return heap;
},

CleanUp: function() { // Cleans up changes made by any previous path search
    var x, y, g = AS.Grid;

    var limX = g.length - 3;
    var limY = g[0].length - 3;

    for (x = 2; x < limX; x++) {
        for (y = 2; y < limY; y++) {
            if (g[x][y].CoorType === AS.CoorType.VISITED) {
                g[x][y].CoorType = AS.CoorType.NOTHING;
                delete g[x][y].Parent;
            }
        }
    }
}

Я понял, что иногда мои объекты, которые должны двигаться в соответствии с путем, возвращенным FindPath, пропускают один шаг. Затем я увидел то, что я описал выше.

введите описание изображения здесь

1 ответ

Решение

Добавив две строки в do {} while (pn.Parent):

do {
    pn = cn.Parent;
    ds.push({
        Dir: cn.Y - pn.Y !== 0 ? cn.Y - pn.Y < 0 ? AS.Direction.UP : AS.Direction.DOWN : cn.X - pn.X > 0 ? AS.Direction.RIGHT : AS.Direction.LEFT,
        Node: cn});
    console.log(ds.length); // Added this line,
    console.log(ds);        // and this one
    cn = pn;
} while (pn.Parent);

Я понял, что console.log (ds) печатает ds так же, как и после вызова GameLoop(), который в какой-то момент вызовет AS.FindPAth, а console.log (ds.length) печатает ds.length как это было в то время, когда я попросил, чтобы это было напечатано.

Поскольку до конца GameLoop() я удалял последний элемент пути, возвращенный моим FindPath() (nextDirection = path.pop()), console.log(ds) печатал сам, пропуская один элемент.

Тем не менее, javascript заставляет сходить с ума, когда он делает такие вещи, как печать состояния объекта, как это будет позже, а не так, как во время console.log ()...

Другие вопросы по тегам