关于对象类型的引用问题

今天我想说一个我第二次犯过的错误,为什么是第二次呢?因为我之前公司的那位老大帮我解释过这个问题,但是最近又犯了这个错误,以此博文作为检讨。

到底是什么错误呢?我们慢慢来说。

由于是在AngularJs的环境下,作用域$scope对象上绑定属性和方法时出的问题,所以我尽量还原当时的场景,这样更逼真些,也更能说明问题。

当时是希望将所有提示信息放在$scope.msg.showMsg这个数组中,然后在页面上显示出来

最初的代码是这样的

$scope.msg={
    showMsg:[],
    msgCollection:{
        "required":"用户名不能为空",
        "pattern":"用户名必须是字母",
        "maxlength":"用户名最长10位",
        "minlength":"用户名至少3位"
    }
};
$scope.change=function(err){
    //先将显示信息的数组清空
    $scope.msg.showMsg=[];
    for(var attr in $scope.txtCollection){
        if(err[attr]){
            //将返回值为true的信息加到结果数组中
            $scope.msg.showMsg.push($scope.txtCollection[attr])
        }
    }
    if($scope.msg.showMsg.length==0){
        //如果通过验证,就显示对勾
        $scope.msg.showMsg=["√"];
    }
};

这个时候没什么问题

但是$scope.change函数里面多次用到了$scope.msg.showMsg这个数组,因此很自然想用一个变量把它存起来,于是代码变成了这样

$scope.msg={
    showMsg:[],
    msgCollection:{
        "required":"用户名不能为空",
        "pattern":"用户名必须是字母",
        "maxlength":"用户名最长10位",
        "minlength":"用户名至少3位"
    }
};
$scope.change=function(err){
    //先将显示信息的数组清空
    var showMsg=$scope.msg.showMsg;
    showMsg=[];
    for(var attr in $scope.txtCollection){
        if(err[attr]){
            //将返回值为true的信息加到结果数组中
            showMsg.push($scope.txtCollection[attr])
        }
    }
    if(showMsg.length==0){
        //如果通过验证,就显示对勾
        showMsg=["√"];
    }
};

但是这样一来,我预览之后发现,页面上什么都显示不出来了,后来我就找老大问为什么

老大说:“你的showMsg清空用的方法是直接赋值一个新的数组对象,这样的话showMsg数组对象和$scope.msg.showMsg数组对象之间的指针关系就会断掉,你对showMsg做的修改就不会影响到$scope.msg.showMsg了,所以效果就出不来了

解决方案也很简单,清空数组有两种方法,除了赋值一个新数组之外,还有另外一种方法就是showMsg.length=0,这样一来,修改的是showMsg和$scope.msg.showMsg共同指向的那个对象的length属性,而并没有做对象覆盖操作,所以这种方法是可以的

当然在此多说一句,在Java或C#里面属性一般都是私有属性,是不能被轻易修改的,所以其实修改数组的length这本身就是js的一个bug,但是我们利用了这个bug清空了数组

其实,之前我还遇到过这样一个问题

当时是希望利用对象是地址传递这样一个特性,希望将一个空对象传入初始化函数中进行初始化,具体的代码如下:

//这里是一个插件的定义
function Table(config){
    this.aaa=config.aaa;
    this.bbb=config.bbb;
}

//初始化插件的方法,在此希望传入哪个对象就初始化哪个对象
function initTable(inst){
    var config={
        aaa:"aaa1",
        bbb:"bbb1"
    };
    inst=new Table(config);
}

var list1=null;
initTable(list1);
console.log(list1);//但是这里得到的结果仍然是nul

具体的原因就不做详细解释了,和上面的问题一样,这次以一张图来说明

原文地址:https://www.cnblogs.com/zhaohuiziwo901/p/4622430.html