回頭看看,那些曾經陪伴我的低端錯誤【2013-12-26號新更新】


    痛苦就是財富,這純屬扯蛋,痛苦之后的思考,才會是財富。知識也是一樣的道理,只知道一味的着急前進,卻忘記自己留下的腳印,如果沒有經過整理,思考,消化,吸收的過程,那它只是短暫的停留在自己的大腦里面。

    這些看似簡單問題,是我正式從9月份正式踏入程序員行業以來經驗總結,若有什么不好的地方,希望大家一定要指出,兼聽則明,偏信則暗^_^

 一,正確的使用eval()

第一次使用eval(),將后台寫的json格式字符串處理成json對象數組

var jsonstr = "{name:'test',age:18}";

var jsonobj = eval(jsonstr);

//拼接過程

錯誤提示:

SyntaxError: invalid label

 

寫到這里老是報錯,我心想,不對呀,怎么拿不到對象呢?

為什么會這樣?

原因在於:eval本身的問題。 由於json是以”{}”的方式來開始以及結束的,在JS中,它會被當成一個語句塊來處理,所以必須強制性的將它轉換成一種表達式。

加上圓括號的目的是迫使eval函數在處理JavaScript代碼的時候強制將括號內的表達式(expression)轉化為對象,而不是作為語句(statement)來執行。舉一個例子,例如對象字面量{},如若不加外層的括號,那么eval會將大括號識別為JavaScript代碼塊的開始和結束標記,那么{}將會被認為是執行了一句空語句。所以下面兩個執行結果是不同的:
alert(eval("{}"); // return undefined
alert(eval("({})");// return object[Object]

如何解決?

var josnobj = eval("("+jsonstr+")");

或者這樣

 eval("var jsonobj = " + jsonstr);

二,ajax的緩存

相信有寫過圖片驗證碼或者經常調用ajax的同學會遇到這種問題。

示例:

 

數據庫:
id(主鍵) pid name
1 11 test1
2 11 test2

如圖所示,pid為11 有兩個name test1,test2

第一次請求:

$.get("Handler.ashx",{mod:"get",pid:11},function(data){

  alert(data);

});

顯示值: test1,test2

數據庫變動:

id(主鍵) pid name
2 11 test2

 

第二次請求:

$.get("Handler.ashx",{mod:"get",pid:11},function(data){

  alert(data);

});

顯示值: test1,test2

為什么會這樣?

監視請求后發現,第二次請求壓根就沒有進入到Handler.ashx文件中去,這次請求直接進入緩存中,原來,我們的瀏覽器已經很聰明了,對於ajax請求的參數相同時,他會自動的保存上一次請求得到的數據,圖片的緩存也是這樣的,當你第一次打開一個網站時候,你會發現相當的慢,第二次打開的時候就相當的快,這個時候,瀏覽器不是去請求網站的服務傳送圖片,而是直接在本地的緩存中取到。

那如何解決?

既然你的參數是一樣的,那我讓參數不一樣就可以了。

$.get("Handler.ashx",{mod:"get",pid:11,random:Math.random()},function(data){

  alert(data);

});

每次都會請求一個不同的參數,這樣瀏覽器會讓為是不同的請求而不會去緩存

另外一種方法是將$.get 換成$.ajax()

$.ajax()下有一個參數是這樣的,cache:false 將設置成不緩存

請參考:$.ajax()的參數

=============由於時間關系,暫時寫到這里,明天更新=============

三,json對象數組的前台拼接

正常的拼接過程:

var jsonstr = "";
//循環遍歷json數組
for(var i=0;i<jsonobjs.length;i++){
  jsonstr +="<tr>";
  jsonstr +="<td>"+jsonobjs[i].name+"</td>";
  jsonstr +="<td>"+jsonobjs[i].age+"</td>";
  jsonstr +="<td>"+jsonobjs[i].id+"</td>";
  jsonstr +="<td>"+jsonobjs[i].createtime+"</td>";
  jsonstr +="<td>"+jsonobjs[i].typename+"</td>";
  //........n個屬性都拼接出來
  jsonstr +="<td>"+jsonobjs[i].typeid+"</td>";
}
//加入到table里面去
$("#tablelist").append(jsonstr);

老大看了以后,說你知道一個對象的屬性也可以循環獲取嗎?

不知道...

你知道你可以用數組來操作jsonstr字符串的拼接嗎?

不知道...

你知道你可以使用innerHTML來進行動態生成么?

不知道...

改后的代碼:

var strarr = [];
var objlength = jsonobjs.length;
for(var i=0;i<objlength ;i++){
  strarr.push("<tr>");
  for(var objproperty in jsonobjs[i]){
    strarr.push("<td>");
    strarr.push(jsonobjs[i][objproperty ]);
    strarr.push("</td>");
  }
 document.getElementById("tblist").innerHTML = strarr.join(" ");
}

為什么要這樣寫?

1.當進行大量的字符串拼接的時候,使用數組的push方法效率要遠遠的高於+=的操作符,這是我經過實驗和查資料后得到的結論,這個道理同樣適用於C#的StringBuilder的Append方法(話說面試里面就有考到過).

2.當進行大量的循環操作的時候,需要將數組length屬性拿出來,這樣避免每次循環都會進行數組長度的計算,可以提高效率.

3.在能使用動態生成DOM對象的時候,如果對象內有少量的節點,或者沒有結點,可以將結點提出來,然后使用innerHTML屬性進行賦值,這樣速度會快於appendChild()方法;

寫代碼,細節真的很重要。

另外推薦轉載:30個提高Web程序的執行效率的好經驗

四,動態生成的DOM對象 

代碼示例:

<html>
 <head>
 	<script type="text/javascript">
      
        window.onload = function(){
                //為btnadd注冊事件
        	document.getElementById("btnadd").onclick = function(){
        		document.getElementById('dvbody').innerHTML ="<span id='sptest'>mytest</span>";
        	}
        	//為生成的span標簽注冊事件
        	document.getElementById("sptest").onclick = function(){
        		alert("click me");
        	}
        }
 	</script>
 </head>
 <body>
 	 <input type='button' value='產生span標簽' id="btnadd" />
 	 <div id="dvbody">
 	 </div>
 </body>
</html>

當我點擊span標簽的時候,壓根就沒有發生我要的效果呀?

為什么會這樣?

打開FireBug調試看看,我去,還是沒有任何的異常。看了半天,最后才明白,原來就是因為采用的動態生成的試,所以當離開btnadd.onclick注冊事件函數的時候為動態生成的sptest注冊事件,這樣脫離了他的范圍,壓根就找不到這個標簽.所以應該這樣寫

如何解決?

<html>
 <head>
 	<script type="text/javascript">
      
        window.onload = function(){
        	document.getElementById("btnadd").onclick = function(){
        		document.getElementById('dvbody').innerHTML ="<span id='sptest'>mytest</span>";
        		//保持上下緊密聯系一起
        		document.getElementById("sptest").onclick = function(){
        		alert("click me");
        	    }
        	}

    
        }
 	</script>
 </head>
 <body>
 	 <input type='button' value='產生span標簽' id="btnadd" />
 	 <div id="dvbody">
 	 </div>
 </body>
</html>

五,服務器控件隱藏

有些同學會問,呀,這你也出問題?Visiable=false不就可以了?對呀,頁面設置的他的可見性,在頁面加載完畢后,可以清晰看到已經不存在了。可是,如果你需要用JS操作這個控件時候,你會發現:

   這個控件壓根就沒有了!

Visiable= true后查看的源代碼

Visiable=false查看的源代碼:

可以很清晰看到,div中壓根就沒有控件,那控件去哪里了呢?轉換成了ViewState了。

應該怎么做?

直接設置他的可見性那整個控件又沒有了,可是這個button卻只有一個Visiable屬性可以設置他的可見性,如何是好?我問我同事,我同事啥也沒有說,跑過來寫下這行代碼.

  <asp:Button Text="text" runat="server" ID="btnaddo" Visible="true" style="display:none"/>

我去!竟然這么簡單,對呀,就是這么簡單。

如什么會這樣?

服務器控件的本質是什么?

網頁的實質就是html標簽+控件樹+一系列的控件的生命周期(方法),那服務器控件的本質所展現的內容也只能是html標簽,那既然是標簽,為什么不可以直接用style屬性呢?

 六,sql的參數未賦值

1  string sqlstr = "select * from t_d_test where name=@name and age = @age and address = @address";
2             SqlParameter[] parms = new SqlParameter[] 
3             {
4                 new SqlParameter("@name","test"),
5                 new SqlParameter("@age",1),
6                 new SqlParameter("@address","test1")
7             };
8             DataTable dt = GetDataTable(sqlstr, parms);

這是一次很簡單的獲得DataTable過程,然后有的時候,sql語句需要動態的變化,

比如:

 string sqlstr = "select * from t_d_test where name=@name and age = @age ";
            SqlParameter[] parms = new SqlParameter[] 
            {
                new SqlParameter("@name","test"),
                new SqlParameter("@age",1),
                new SqlParameter("@address","test1")
            };
            DataTable dt = GetDataTable(sqlstr, parms);

sql語句中很明顯只有兩個參數,但是我還去定義了parms為三個參數,執行的時候才發現,那叫一個速度慢哦,一直debug到最后一行方法時才發現,我壓根在sql語句中定義@address,最后速個的執行過程一直卡在這里。最后直接delete這個參數后,直接執行。

七,自增長列賦值插入[這個就不演示了- - 太可笑了]

八,服務器控件DropDownList的綁定后詭異的SelectIndexChange事件失效

    在綁定數據后,服務器控件進行selectindexchange事件里面,查看不論怎么選擇,當前選中項的值一直都是不會變化的,為何?

    在經過google后,發現問題所在DropDownList的子集item的屬性text 及value其實是一種字典的形式存在的,就是說一個Key對應唯一的Value,Value是不可以重復的

解決方法:

    保證value不重復


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM