今天在用面向?qū)ο筮M(jìn)行編程的過程中,遇到了一個(gè)隱藏得很深的坑,在此與大家分享一下,避免以后再犯,也給大家提供一個(gè)參考。
先看一下問題代碼:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
#contents{
position: relative;
}
#contents div{
width: 200px;
height: 200px;
border: 1px dashed red;
position: absolute;
display: none;
}
</style>
</head>
<body>
<div id="titles">
</div>
<div id="contents">
</div>
<script type="text/javascript">
function SelectCard(btn, div){
this.btn = btn;
this.div = div;
}
SelectCard.prototype.init = function(){
this.btn.onmouseover = function(){
this.div.style.display = "block";
}.bind(this);
this.btn.onmouseout = function(){
this.div.style.display = "none";
}.bind(this);
}
SelectCard.handleJson = function(resultText){
var objs = JSON.parse(resultText);
var data = objs.data;
for(var i = 0, len = data.length; i < len; i++){
var btns = document.createElement("button");
var divs = document.createElement("div");
btns.innerHTML = data[i].title;
divs.innerHTML = data[i].content;
titles.appendChild(btns);
contents.appendChild(divs);
var xxk = new SelectCard(btns, divs);
xxk.init();
}
}
(function(){
var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
xhr.open("GET", "data.json", true);
xhr.onreadystatechange = function(){
if(xhr.readyState == 4){
if(xhr.status == 200){
SelectCard.handleJson(xhr.responseText);
}
}
}
xhr.send(null);
})();
</script>
</body>
</html>
已知,所獲取的 data.json數(shù)據(jù)無誤,且亦無拼寫錯(cuò)誤和功能性錯(cuò)誤。
乍一分析,其實(shí)也找不出到底是什么原因?qū)е马撁鏌o法輸出,通過查看控制臺(tái)出現(xiàn)如下報(bào)錯(cuò):

經(jīng)過進(jìn)一步查看可以看到,SelectCard.handleJson 函數(shù)中所傳入的參數(shù),并不是我們所期望的 xhr.responseText 數(shù)據(jù),而是一個(gè)匿名函數(shù)。

通過調(diào)試獲取所傳入的參數(shù)resultText并向控制臺(tái)輸出

查看控制臺(tái)輸出結(jié)果我們可以發(fā)現(xiàn)所傳入的參數(shù)居然是它下面的 自執(zhí)行的匿名函數(shù) 本身,而非我們所期望的 xhr.responseText

那么問題來了,為何我們所設(shè)定的 “自執(zhí)行的匿名函數(shù)” 會(huì)被當(dāng)做參數(shù)傳到了上面的函數(shù)中呢?
在平常編程的過程中,我們常常會(huì)在一句話的末尾加上分號(hào)來表示這句話的結(jié)束,然而對(duì)于函數(shù),我想大部分人應(yīng)該習(xí)慣性的不會(huì)加分號(hào)來進(jìn)行分隔,因?yàn)楹瘮?shù)與函數(shù)之間,函數(shù)與變量之間即使沒有分號(hào),也不會(huì)對(duì)彼此產(chǎn)生任何影響。
然而,有一個(gè)東西寫在函數(shù)后卻會(huì)對(duì)前面的函數(shù)產(chǎn)生影響,而且一般很難察覺,它就是 自執(zhí)行的匿名函數(shù)。
由于這一匿名函數(shù)被設(shè)定為自執(zhí)行,這就使得這個(gè)匿名函數(shù)無形中被 括號(hào) 包裹起來,即使與它上面的函數(shù)有換行的分隔也會(huì)被當(dāng)做參數(shù)傳入它上面的函數(shù)中,這一隱性影響使得 我們始終無法獲得 自執(zhí)行的匿名函數(shù)中的目標(biāo)參數(shù),因?yàn)樗厦娴暮瘮?shù)已經(jīng)把整個(gè)自執(zhí)行的匿名函數(shù)當(dāng)做了要傳入的參數(shù)。
那么,肯定有人會(huì)說,把這個(gè)自執(zhí)行的匿名函數(shù)放到他上面的函數(shù)的前面不就好了?
這確實(shí)是一個(gè)方法,不過你仔細(xì)看看上面提供的問題代碼會(huì)發(fā)現(xiàn),這個(gè)自執(zhí)行的匿名函數(shù)的前一個(gè)函數(shù)的前面又是一個(gè)函數(shù),那么這個(gè)自執(zhí)行的匿名函數(shù)便又被當(dāng)做了參數(shù)傳入上面的函數(shù)中,只有當(dāng)調(diào)整位置后的 自執(zhí)行匿名函數(shù) 的前面再找不到函數(shù)的時(shí)候,這個(gè)方法才是有效的。
不過最好的方法是:
保證 -自執(zhí)行的匿名函數(shù)- 的前面一句話的末尾始終有 -分號(hào)- 即可。
這樣的話,即使這一 自執(zhí)行的匿名函數(shù) 前面是函數(shù),也不會(huì)有任何影響了。

以上純屬個(gè)人學(xué)習(xí)總結(jié),如有疏漏或者不足之處還望指正,謝謝!