标签:
今天我想说一个我第二次犯过的错误,为什么是第二次呢?因为我之前公司的那位老大帮我解释过这个问题,但是最近又犯了这个错误,以此博文作为检讨。
到底是什么错误呢?我们慢慢来说。
由于是在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
具体的原因就不做详细解释了,和上面的问题一样,这次以一张图来说明
标签:
原文地址:http://www.cnblogs.com/zhaohuiziwo901/p/4622430.html