先来看一段代码:
<!-- lang: js -->
var iCurId, nItem,
nFragment = document.createDocumentFragment();
for(var i=0,j=aResPat.length; j>i; i++){
nItem = document.createElement("tr"),
iCurId1 = aResPat[i].ID,
nItem.setAttribute("data-patid", iCurId),
/*留意此处代码*/
nItem.onclick = function(){
/*争议之处, 注意nItem*/
patient.choosePatient( nItem.getAttribute("data-patid") );};
},
nItem.innerHTML = '<td style="width: 150px;">'+ aResPat[i].Name +'</td>'
+ '<td style="width: 150px;">'+ aResPat[i].MRNumber +'</td>'
+ '<td style="width: 50px;">'+ translateSex( aResPat[i].Sex ) +'</td>'
+ '<td>'+ aResPat[i].Diagnosis +'</td>',
nFragment.appendChild(nItem);
}
$("#table").append(nFragment);
在上述代码中,如果对#table里面的tr进行点击,那么他执行的时候,nItem获取回来的"data-patid"是属于最后定义的tr元素的,而不是编写代码理想中的每个tr对应自己的nItem。不是的!在执行的时候,这样写的nItem是指向最后定义的一个。
原因我想是nItem变量只会保存一个,你每次覆盖nItem,到最后onclick方法执行时寻找nItem,只会指向最后一次的变量。所以,即使上述代码中改成在for
循环里声明nItem var nItem = document.createElement("tr")
,其结果都一样。
对付这种情况,可以采用以下两种办法: 一、
<!-- lang: js -->
nItem.onclick = function(){
/*采用this指向当前点击的tr元素*/
patient.choosePatient( this.getAttribute("data-patid") );};
}
二、
<!-- lang: js -->
/*以闭包的模式将nItem传入执行方法里面*/
nItem.onclick = (function(nItem){
return function(){patient.choosePatient( nItem.getAttribute("data-patid") );};
})(nItem)
另外,使用Function.bind()方法绑定当前变量指向也可,不过效果和第一种方法差不多:
<!-- lang: js -->
nItem.onclick = (function(){
patient.choosePatient( this.getAttribute("data-patid") );}
).bind(nItem), /*即时绑定当前nItem变量指向*/
大家也有遇到类似的情况么?!欢迎讨论~