Почему переменная меняет своё значение?

Есть код функции, в ней в начале объявляется переменная
var nullPoint = arrayOfInitialPositions[0];
.....
позже где-то значение arrayOfInitialPositions[0] меняется и оказывается, что и значение nullPoint при этом поменяется, хотя не должно.
Возможно причина этому в том, что в js присваивания носят характер ссылок.
Не могли бы Вы объяснить причину и рассказать как избежать этого в дальнейшем?
Код функции:
"use strict";
/**
 * Created by alexey on 18.11.15.
 */
function FABRIK(){
}

FABRIK.algorithm = function(arrayOfInitialPositions, TargetPoint, tol) {
    // Инициализация переменных
    // узел pn = [[x,y,z]]
    var // newArrayOfInitialPositions = [new Float32Array(arrayOfInitialPositions.length)[new Float32Array(TargetPoint.length)]],
        // newArrayOfInitialPositions = new Float32Array(arrayOfInitialPositions.length),
        distBeetweenJoints = [], // дистанция между сопряжёнными узлами (длины звеньев от узла до ближайшего узла)
        distBeetweenJointsAndTarget = [], // отношение дистанций от узла до узла и от узла до цели
        TargetPoint = TargetPoint, // цель, целевая точка t = [x,y,z]
        distBeetweenStartPointAndTarget, // дистанция между стартовым узлом и целью, целевой точкой
        lambdaDistance = [], // отношение
        tol = tol, // максимально допустимое растояние между конечным узлом и целью
        sumOfInitialDistances = 0; // переменная для общей дистанции между узлами
    // Функция, вычисляющая расстояние между 2 точками
    // Расстояние между 2 точками выч. по формуле
    // (x1-x2)^2+(y1-y2)^2+(z1-z2)^2
    function distBetweenPoints(point_1, point_2) {

        var x = Math.pow((point_1[0] - point_2[0]), 2);
        var y = Math.pow((point_1[1] - point_2[1]), 2);
        var z = Math.pow((point_1[2] - point_2[2]), 2);

        return Math.sqrt((x + y + z))

    }

    // Вычисляем длину между соседними узлами
    // метод массива .length возвращает количество его элементов
    for (var i = 0, len = arrayOfInitialPositions.length; i < len - 1; i++) {
        distBeetweenJoints[i] = distBetweenPoints(arrayOfInitialPositions[i], arrayOfInitialPositions[i + 1]);
        console.log("Расстояние между точками ", i, " и ", (i + 1), " = ", distBeetweenJoints[i]);
    }
    // расстояние между стартовым узлом и целевой точкой
    distBeetweenStartPointAndTarget = distBetweenPoints(arrayOfInitialPositions[0], TargetPoint);
    console.log("Расстояние между стартовым узлом и целевой точкой " + distBeetweenStartPointAndTarget);

    // Сложение дистанций между узлами
    sumOfInitialDistances = distBeetweenJoints.reduce(function (sum, current) {
        return sum + current
    });
    console.log("Общее расстояние между узлами: " + sumOfInitialDistances);
    // Сравниваем общее расстояние между узлами(общую длину) и расстояние до цели
    // Если цель не достежима, то максимально приближаемся к ней
    // Если нет, то приближаемся к ней, пока не достигнем максимального отдаления
    // заданное переменной tolerance
    if (distBeetweenStartPointAndTarget > sumOfInitialDistances) {
        var newArrayOfInitialPositions = arrayOfInitialPositions;
        window.alert("Цель не достижима!");
        for (var i = 0, len = arrayOfInitialPositions.length; i < (len - 1); i++) {

            // Найдем дистанцию r[i] между целью t и узлом p[i]
            distBeetweenJointsAndTarget[i] = distBetweenPoints(arrayOfInitialPositions[i], TargetPoint);
            // Отношение дистации между сопряжёнными узлами и дистанацией между узлом и целью
            lambdaDistance[i] = distBeetweenJoints[i] / distBeetweenJointsAndTarget[i];

            // начало вычисления первого и второго слагаемых
            // для удобства формула была разделдена на 2 этапа - функции:
            // вычисление первого слагаемого и второго
            var firstStep = arrayOfInitialPositions[i].map(function (item) {
                return (item * (1 - lambdaDistance[i]))
            });
            var secondStep = TargetPoint.map(function (item) {
                return item * lambdaDistance[i]
            });
            console.log("firstStep ", firstStep);
            console.log("secondStep ", secondStep);
            // конец вычисления первого и второго слагаемых
            for (var j = 0; j < firstStep.length; j++) {
                // новая позиция узлов для максимальной близости конечного к цели
                console.log(firstStep[j] + secondStep[j]);
                var sumOfFirstStepAndSecond = firstStep[j] + secondStep[j];
                newArrayOfInitialPositions[i + 1][j] = sumOfFirstStepAndSecond;
            }
        }
        arrayOfInitialPositions.forEach(function (item, i) {
            console.log("Старая позиция Node_" + i + " = "
                , item);
        });
        newArrayOfInitialPositions.forEach(function (item, i) {
            console.log("Новая позиция Node_" + i + " = "
                , item);
        });
        // результат работы алгоритма - массив новых значений координат, алгоритм не выполняет сам никаких перестановок, только просчёт
        return newArrayOfInitialPositions;
    }
    else {
        var count = 1;
        window.alert("Цель достижима!");
        // если цель достижима, то сохраним позицию нулевого узла
        var nullPoint = arrayOfInitialPositions[0];
        var DIFa = distBetweenPoints(arrayOfInitialPositions[arrayOfInitialPositions.length - 1], TargetPoint);
        console.log("DIFa = " + DIFa);
        do {
            // Этап 1: прямое следование
            // ставим конечный узел arrayOfInitialPositions[arrayOfInitialPositions.length] на позицию цели
            arrayOfInitialPositions[arrayOfInitialPositions.length - 1] = TargetPoint;
            for (var len = arrayOfInitialPositions.length, i = (len - 2); i >= 0; i--) {
                // Найдем дистанцию r[i] между целью t и узлом p[i]
                distBeetweenJointsAndTarget[i] = distBetweenPoints(arrayOfInitialPositions[i + 1], arrayOfInitialPositions[i]);
                // Отношение дистации между сопряжёнными узлами и дистанацией между узлом и целью
                lambdaDistance[i] = distBeetweenJoints[i] / distBeetweenJointsAndTarget[i];
                //console.log(lambdaDistance[i]);
                // начало вычисления первого и второго слагаемых
                // для удобства формула была разделдена на 2 этапа - функции:
                // вычисление первого слагаемого и второго
                var firstStep = arrayOfInitialPositions[i].map(function (item, j, array) {
                    return (arrayOfInitialPositions[i + 1][j] * (1 - lambdaDistance[i]))
                });
                var secondStep = arrayOfInitialPositions[i].map(function (item, j) {
                    return (item * lambdaDistance[i])
                });
                // конец вычисления первого и второго слагаемых
                for (var j = 0; j < firstStep.length; j++) {
                    // новая позиция узлов для максимальной близости конечного к цели
                    var sumOfFirstStepAndSecond = firstStep[j] + secondStep[j];
                    arrayOfInitialPositions[i][j] = sumOfFirstStepAndSecond;
                }
            }

            // Этап 2: обратное следование
            // Восстанавливаем корневому элементу его позицию
            arrayOfInitialPositions[0] = nullPoint;
            //console.dir(arrayOfInitialPositions);
            for (var i = 0, len = arrayOfInitialPositions.length - 1; i < (len - 1); i++) {
                // Найдем дистанцию r[i] между целью t и узлом p[i]
                distBeetweenJointsAndTarget[i] = distBetweenPoints(arrayOfInitialPositions[i + 1], arrayOfInitialPositions[i]);
                //console.log(i,distBeetweenJointsAndTarget[i],"\n");
                // Отношение дистации между сопряжёнными узлами и дистанацией между узлом и целью
                lambdaDistance[i] = distBeetweenJoints[i] / distBeetweenJointsAndTarget[i];

                // начало вычисления первого и второго слагаемых
                // для удобства формула была разделдена на 2 этапа - функции:
                // вычисление первого слагаемого и второго
                var firstStep = arrayOfInitialPositions[i].map(function(item){ return (item * (1 -lambdaDistance[i])) });
                //console.log(firstStep);
                var secondStep = arrayOfInitialPositions[i].map(function(item,j,arr){ return (arrayOfInitialPositions[(i + 1)][j] * lambdaDistance[i]) });
                //console.log(secondStep);
                // конец вычисления первого и второго слагаемых
                for(var j = 0; j < firstStep.length; j++){
                    // новая позиция узлов для максимальной близости конечного к цели
                    //console.log("Привет!, это сумма firstStep и secondStep",firstStep[j] + secondStep[j]);
                    var sumOfFirstStepAndSecond = firstStep[j] + secondStep[j];
                    arrayOfInitialPositions[i+1][j] = sumOfFirstStepAndSecond;
                }
            }
            console.log("интераций на решение задачи",count++);
            DIFa = distBetweenPoints(arrayOfInitialPositions[arrayOfInitialPositions.length - 1], TargetPoint);
            //console.log(DIFa);
        }
        while (DIFa > tol);
    }
    return arrayOfInitialPositions;

};

репозиторий на GitHub
  • Вопрос задан
  • 227 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы