javascript中的call()和apply應用

         在javascript開發過程當中,若是有看過幾個javascirpt代碼庫,就會發現常用到call()和apply()函數,call()和aplly()結合javascript容許傳遞函數名,這種便利性在javascript開發過程當中是毋庸置疑的。call()和apply()函數的實現做用是同樣的,只不過call()是逐個傳遞參數,而apply()容許傳遞參數數組,這個徹底根據實際須要進行選擇。javascript

call()和apply()的第一個參數是代碼執行的上下文。當call()和apply()函數的第一個參數傳遞爲null時,則這個時候的上下文爲window.call()和apply()函數在使用上比較難理解一點,若是可以理解透了將很是的喜歡使用。html

  • 下面是一個異步提交表單,並異步回調並經過call()函數實現給回調函數動態傳遞參數的過程。

 

function addSelectOption(selectId, optionValue, optionText, className){
	var oSelect = document.getElementById(selectId);
	
	if(oSelect){
		var option 		= document.createElement("option");
		option.value 	= optionValue;
		option.text  	= optionText;
		
		className = className == "undefined" ? "" : className;

		try{
			option.setAttribute("class", className);
			oSelect.add(option,null);  
		} catch(e){
		    option.setAttribute("className", className);
	            oSelect.add(option);  
		}
		return option;
	 }	
	 return null;
}

/*窗口配置*/
var dialogSetting = {
        refrain    : 0,
        queue     : []
};

/*在selectId上綁定事件*/
$("#selectId > option").eq(0).click({
    newDialog(url, this, jsonParse);
});
function newDialog(url, obj, fnCallback){
    art.dialog({
        title    : '歡迎',
        content    : document.getElementById("dialogBody"),
        ok        : function () {
/*異步提交函數*/
            postDataToServer(url, obj, fnCallback);
            return false;
        },
        okValue: '提  交',
        cancelValue: '關 閉',
        cancel: function () {
            $("#data").val("");
        }            
    });    
    
    return false;
}
  
/*提交表單數據到服務端*/
function postDataToServer(url, obj, fnCallback){
    var message     = "";
    var dataValue     = document.getElementById("data").value;
    
    if(dataValue.length == 0){
        message = "請填寫內容!";
        $("#lbl_error").html(message);
        
        return false;
    }
    
    /*判斷是否容許重複*/
    if(dialogSetting.refrain == 0){
        if(("," + dialogSetting.queue.join(",") + "," ).indexOf(","+ dataValue +",") >=0){
            message = "提交內容已存在,不容許出現重複!";
            $("#lbl_error").html(message);
            return false;
        }
    }
    
    $.post(url,{
        data : dataValue    
    }).success(function(responseData, textStatus, jqXHR) {
        eval("var rtnJson="+ responseData + ";");
        
        if(rtnJson.state == "1"){
            /*將提交的內容插入隊列*/
            var permitName = rtnJson.dataName;
            dialogSetting.queue.push(permitName);
            
            fnCallback.call(obj, obj, rtnJson);
            
            message = "數據提交成功!";
        }else{
            message = "數據提交失敗,請從新嘗試";
        }
    }).error(function(XMLHttpRequest, textStatus  , errorThrown) { 
        message = "網絡通信異常,請從新嘗試登陸!";
    }).complete(function(data) {     
        $("#lbl_error").html(message);    
    });         
}

function jsonParse(obj, json){    
    if(obj && json.state == 1){
        var option = document.createElement("option");
        option.text     = json.dataName;
        option.value     = json.dataKey;
        
        document.getElementById("gather").add(option,obj);  
        
        /*選中指定的option*/
        selSpecialOption("selectId", document.getElementById("selectId").options.length - 2);        
    }
}




 

 

 

在上面的例子中,fnCallback回調函數就是jsonParse函數,jsonParse有兩個參數,所以call()函數中須要傳遞相應的兩個參數,同時因爲call()的第一個參數是指定上下文對象,而這個例子中的上下文其實就是下拉id爲selectId的第一個option對象,即參數obj = $("#selectId > option").eq(0)。所以java

fnCallback.call(obj, obj, rtnJson);

等同於

jsonParse.call($("#selectId > option").eq(0),$("#selectId > option").eq(0),rtnJson)
其中第一個$("#selectId > option").eq(0)爲call調用的上下文,第二個$("#selectId > option").eq(0)爲jsonParse須要的參數

 

在apply()函數中實現以上的結果就是json

 

fnCallback.apply(obj, [obj, rtnJson]);

jsonParse.call($("#selectId > option").eq(0),[$("#selectId > option").eq(0),rtnJson])
相關文章
相關標籤/搜索