jquery中apply與call的使用
每一個Function物件都有一個apply()方法和一個call()方法
A物件有一個方法,而B物件因為某種不可言說的情況也需要用到一樣的方法,那麼這時候我們是單獨為B擴充套件個方法呢,還是借用一下A的方法呢?當然是借用A的啦,既完成了需求,又減少了記憶體的佔用
apply:呼叫一個物件的一個方法,用另一個物件替換當前物件。例如:B.apply(A, arguments);即A物件應用B物件的方法。
function.apply(obj[,argArray])
只接收兩個引數,其中第二個引數必須是一個陣列或者類陣列,這也是這兩個方法很重要的一個區別
call:呼叫一個物件的一個方法,用另一個物件替換當前物件。例如:B.call(A, args1,args2);即A物件呼叫B物件的方法。
function.call(obj[,arg1[, arg2[, [,.argN]]]]])
- 呼叫
call
的物件必須是個函式function call
的第一個引數將會是function改變上下文後指向的物件,如果不傳,將會預設是全域性物件window
- 第二個引數開始可以接收任意個引數,這些引數將會作為function的引數傳入function
- 呼叫
call
的方法會立即執行
function add(a,b){ return a+b; } function sub(a,b){ return a-b; } var a1 = add.apply(sub,[4,2]); //sub呼叫add的方法 var a2 = sub.apply(add,[4,2]); alert(a1); //6 alert(a2); //2 /*call的用法*/ var a1 = add.call(sub,4,2);
異同
相同點
都能夠改變方法的執行上下文(執行環境),將一個物件的方法交給另一個物件來執行,並且是立即執行.
一般來說,this總是指向呼叫某個方法的物件,但是使用call()和apply()方法時,就會改變this的指向。
var Pet = { words : '...', speak : function (say) { console.log(say + ''+ this.words) } } Pet.speak('Speak'); // 結果:Speak... var Dog = { words:'Wang' } //將this的指向改變成了Dog Pet.speak.call(Dog, 'Speak'); //結果: SpeakWang --------------------- function Pet(words){ this.words = words; this.speak = function () { console.log( this.words) } } function Dog(words){ //Pet.call(this, words); //結果: Wang Pet.apply(this, arguments); //結果: Wang } var dog = new Dog('Wang'); dog.speak(); ---------------------
不同點
call
方法從第二個引數開始可以接收任意個引數,每個引數會對映到相應位置的func的引數上,可以通過引數名呼叫,但是如果將所有的引數作為陣列傳入,它們會作為一個整體對映到func對應的第一個引數上,之後引數都為空
function func (a,b,c) {}
func.call(obj, 1,2,3)
// function接收到的引數實際上是 1,2,3
func.call(obj, [1,2,3])
// function接收到的引數實際上是 [1,2,3],undefined,undefined
apply
方法最多隻有兩個引數,第二個引數接收陣列或者類陣列,但是都會被轉換成類陣列傳入func中,並且會被對映到func對應的引數上
func.apply(obj, [1,2,3])
// function接收到的引數實際上是 1,2,3
func.apply(obj, {
0: 1,
1: 2,
2: 3,
length: 3
})
// function接收到的引數實際上是 1,2,3
兩個方法該如何選擇?
跟簡單,根據你要傳入的引數來做選擇,不需要傳參或者只有1個引數的時候,用call
,當要傳入多個物件時,用apply
或者,如果需要傳入的引數已經是一個數組或者類陣列了,就用apply
,如果還是單獨的需要逐個傳入的,可以考慮使用call
(如果你不嫌麻煩的話 )
jquery中apply的使用
(function (window, $, undefined) {
// 定義 通用工具方法 擴充套件物件基元
coreUtil = function () { return Object.apply(this, arguments); },
// 定義 jQuery 擴充套件物件基元
coreJquery = function () { return $.apply(this, arguments); },
coreUtil.fn = coreUtil.prototype = {};
coreJquery.fn = coreJquery.prototype = {};
coreJquery.util = coreUtil;
// 獲取當前頁面 url 引數。
// 返回值:該方法返回一個數組,陣列中的每個元素都是一個 JSON 物件,該 JSON 物件包含如下屬性:
// name: 表示 url 引數的名稱;
// value: 表示 url 引數的值;
// 也可以通過陣列訪問器快速訪問某個特定名稱的引數值,方法如:coreUtil.getRequest()["id"]。
coreUtil.getRequest = function () {
var search = location.search;
if (search.substr(0, 1) == "?") { search = search.substr(1, search.length - 1); }
var result = [];
if (search.length > 0) {
var params = search.split("&");
for (var i = 0; i < params.length; i++) {
var param = params[i];
var pos = param.indexOf("=");
var name = param.substring(0, pos);
var value = param.substr(pos + 1);
result.push({ name: name, value: value });
result[name] = value;
}
}
return result;
};
coreUtil.request = coreUtil.getRequest();
})(window, jQuery);
var url = "approve.html?s=" + Math.random()+"&installApplyId="+rows[0].installApplyId;
var installApplyId = $.util.request.installApplyId;
jquery中call的使用
var dgOpts = $.extend({},
opts.dgOpts,
{
onBeforeLoad: function (paras) {
if (opts.dgOpts.onBeforeLoad && $.isFunction(opts.dgOpts.onBeforeLoad))
opts.dgOpts.onBeforeLoad.call(this, paras);
var v = $Core.util.QueryFormSerializeString(searchForm);
paras.querystr = v;
},
onSelect: function (index, row) {
if (opts.dgOpts.onSelect && $.isFunction(opts.dgOpts.onSelect))
opts.dgOpts.onSelect.call(this, index, row);
if (opts.onSelect && $.isFunction(opts.onSelect)) {
var v = opts.onSelect.call(this, index, row);
if (v !== false)
dialog.dialog("close");
}
}
});
grid.datagrid(dgOpts);
$("#listAdd").bind("click", function() {
if(flag){
$("#listAdd").gridselect({
title:'裝置資訊',
dialogWidth: '600', //視窗寬度 預設值600
dialogHeight: "400",//視窗高度 預設值 70%
searchFields: [ //搜尋條件
{
name: "deviceName", //separator 指定後會換行顯示
text: "裝置名稱",
type: "combobox", //控制元件型別 只支援 簡單的表單控制元件 textbox my97 combobox 等簡單控制元件 如果條件過多 可以增加 separator 換行顯示
url: "system/dic/getDicByCode/installdevName", //字典獲取路徑
width: '', //寬度
querytype: "eq",
//hidden: true, //是否隱藏域 預設否
value: '' //預設值
},
{
name: "stockDeviceState", //separator 指定後會換行顯示
text: "狀態",
type: "textbox", //控制元件型別 只支援 簡單的表單控制元件 textbox my97 combobox 等簡單控制元件 如果條件過多 可以增加 separator 換行顯示
//url: "system/dic/getDicByCode/material_type", //字典獲取路徑
width: '', //寬度
querytype: "like",
hidden: true, //是否隱藏域 預設否
value: "1" //預設值
}
],
dgOpts: { //datagrid 引數
url: 'security/devicestock/query',
/* queryParams: {
qqq : '[{"name":"gfy","value":"'+$("#gfyId").val()+'","type":"like"}]',
d:'fff'
},*/
/*onBeforeLoad:function(paras){
paras.querystra +="&id="+$("#gfyId").val();
},*/
columns: [[
{field:'deviceName',title:'裝置名稱',align:'center',width:200,formatter:function (value,row,index) {
return $Core.DicCache.get("installdevName")[value];
}},
{field:'deviceNumber',title:'裝置編號',align:'center',width:200},
{field:'assetNumber',title:'資產編號',align:'center',width:200},
{field:'gfyId',title:'使用使用者',align:'center',width:200,formatter:function(value,row,index) {
return $Core.DicCache.get("publicserviceName")[value];
}},
{field:'productCompany',title:'生產廠家',align:'center',width:200},
{field:'stockDeviceState',title:'裝置狀態',align:'center',width:200,formatter:function(value,row,index) {
return $Core.DicCache.get("stockDeviceState")[value];
}},
]]
},
//選擇一行時 被呼叫 return false 不會關掉視窗
onSelect: function (index, row) {
var newRow = {};
newRow.deviceId = row.stockId;
newRow.deviceName = row.deviceName;
newRow.assetsNumber = row.assetNumber;
newRow.deviceNumber = row.deviceNumber;
newRow.deviceSpec = row.standardModel;
newRow.propertyAscription = "1";
newRow.company = "";
var stockId = row.stockId;
var isAppend = true;
$.each($("#dglist2").datagrid("getRows"), function (j,k) {
if (k.deviceId==stockId) {
isAppend = false;
}
});
if (isAppend) {
$("#dglist2").datagrid("appendRow", newRow);
}
return false;},
onClear: function () { //點選清空按鈕時被呼叫
}
});
flag = false;
}
$("#listAdd").gridselect("show");
});
【其他用途——物件繼承】
由於可以改變this
的指向,所以也就可以實現物件的繼承
function superClass () {
this.a = 1;
this.print = function () {
console.log(this.a);
}
}
function subClass () {
superClass.call(this);
this.print();
}
subClass();
// 1
subClass
通過call
方法,繼承了superClass
的print
方法和a
變數,同時subClass
還可以擴充套件自己的其他方法