javascript中的call()和apply应用
在javascript开发过程中,如果有看过几个javascirpt代码库,就会发现经常使用到call()和apply()函数,call()和aplly()结合javascript允许传递函数名,这种便利性在javascript开发过程中是毋庸置疑的。call()和apply()函数的实现作用是一样的,只不过call()是逐个传递参数,而apply()允许传递参数数组,这个完全根据实际需要进行选择。
call()和apply()的第一个参数是代码执行的上下文。当call()和apply()函数的第一个参数传递为null时,则这个时候的上下文为window.call()和apply()函数在使用上比较难理解一点,如果能够理解透了将非常的喜欢使用。
- 下面是一个异步提交表单,并异步回调并通过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)。因此
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()函数中实现以上的结果就是
fnCallback.apply(obj, [obj, rtnJson]); jsonParse.call($("#selectId > option").eq(0),[$("#selectId > option").eq(0),rtnJson])
wala-wo