记一个坑(值传递和地址传递)

前言

在写业务的时候最近碰到一个坑(也不算吧,就是忙着写业务的时候没想起来这回事,呜呜~),写了一个函数之后传了两个数组进去结果发现传进去的数组当函数执行完之后就改变了。

最后解决方法是在传参之后在函数里深拷贝一份参数

本函数的作用:根据两个数组[x1,x2,x3,…],[y1,y2,y3…]求拟合方程,并求出最大值y和最大值对应的x值


// 深拷贝
function deepClone(obj) {
    let objClone = Array.isArray(obj) ? [] : {};
    if (obj && typeof obj === "object") {
        for (let key in obj) {
            if (obj.hasOwnProperty(key)) {
                //判断ojb子元素是否为对象,如果是,递归复制
                if (obj[key] && typeof obj[key] === "object") {
                    objClone[key] = this.deepClone(obj[key]);
                } else {
                    //如果不是,简单复制
                    objClone[key] = obj[key];
                }
            }
        }
    }
    return objClone;
}
export function getMaxData(arr1, arr2) {  //array1为含水量 ,array2为干密度
    let array1 = deepClone(arr1)
    let array2 = deepClone(arr2)
    let x = new Array();
    let xs = new Array();
    let j = array1.length;
    let pd, w;
    let max;
    let s;
    let max_x = 0;
    let min_x = 0;
    max_x = Math.max(...array1);
    min_x = Math.min(...array1);
    if (!(max_x >= min_x || min_x >= 0)) {
        min_x = 0;
        max_x = 20;
    }
    if (max_x - min_x > 100) {
        return false;
    }
    let global_msg = "线性方程数组:";
    if (array2.length > 0) {
        for (let i = 0; i <= j - 1; i++) {
            x[i] = new Array();
            for (let k = 0; k <= j - 1; k++) {
                x[i][k] = Math.pow(array1[i], j - 1 - k);
            }
        }
        xs = Gauss(x, array2);
        global_msg += "多项式系数:";
        for (let i = 0; i < xs.length; i++) {
            global_msg += xs[i] + ",";
        }
        max = Newton(xs, min_x, max_x, 0.01);
        w = max.split(";")[0];
        pd = max.split(";")[1];
    }
    else {
        pd = "";
        w = "";
    }
    return { maxValue: Number(pd), maxX: Number(w) }
}

// 高斯列主元消去法求解线性方程组
// 返回数组解
function Gauss(x, y) {
    var xs = new Array();
    // 变量区域  i表示行,k表示列
    var i, j, k, tmp, ik, n, mik;
    n = x.length;
    // 消元
    for (let k = 0; k < n; k++) {
        //  选列主元
        mik = -1;
        for (let i = k; i < n; i++) {
            if (Math.abs(x[i][k] * 1) > mik) {
                mik = Math.abs(x[i][k] * 1);
                ik = i;               //当前列系数最大的行
            }
        }
        for (let j = k; j < n; j++) {
            tmp = x[ik][j];
            x[ik][j] = x[k][j];
            x[k][j] = tmp;
        }
        tmp = y[k]; y[k] = y[ik]; y[ik] = tmp;        //把当前行数据和最大列的系数对换
        // 消元
        y[k] = y[k] * 1 / (x[k][k] * 1);
        for (let i = n - 1; i >= k; i--) {
            x[k][i] = (x[k][i] / x[k][k]);
        }

        for (let i = k + 1; i < n; i++) {
            y[i] = y[i] - x[i][k] * y[k];
            for (let j = n - 1; j >= k; j--) {
                x[i][j] = x[i][j] - x[i][k] * x[k][j];
            }
        }
    }
    // 回代
    var s = 0;
    xs[n - 1] = y[n - 1];
    for (let i = n - 2; i >= 0; i--) {
        s = y[i];
        for (let j = i + 1; j < n; j++) {
            s = s - xs[j] * x[i][j];
        }
        xs[i] = s;
    }
    return xs;
}
/*牛顿迭代求多项式的最大值*/
function Newton(xs, min, max, step) {
    console.log(xs, min, max, step, "step");
    var n = xs.length;
    var s = 0;
    var tmp = 1;
    var y;
    var x;
    for (let i = min; i + step < max; i = i + step) {
        // 求多次方
        for (let j = 0; j < n; j++) {
            tmp = Math.pow(i, n - 1 - j)
            s = s + tmp * xs[j];
            tmp = 1;
        }
        if (i == min) {
            x = i;
            y = s;
            s = 0;
            continue;
        }

        if (s > y) {
            x = i;
            y = s;
        }

        s = 0;
    }
    console.log(x, "x", y, "y");
    return x + ";" + y;
}

总结

在JavaScript中,因为其基于原型的继承和动态的数据类型,所有参数的传递方式可以被视为“值传递”。这意味着当你将一个参数传递给一个函数时,你实际上传递的是一个值的副本。如果这个值是一个对象,那么副本实际上是对原对象的引用(地址)。

简单来说:
所有基本类型(例如:Number, String, Boolean, undefined, null)按值传递。
所有对象类型(例如:Object, Array, Function)按引用传递。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值