jQuery中的$.proxy官方描述為:
描述:接受一個函數,然后返回一個新函數,並且這個新函數始終保持了特定的上下文語境。
官方API;
jQuery.proxy( function, context )
function為執行的函數,content為函數的上下文this值會被設置成這個object對象
jQuery.proxy( context, name )
content 函數的上下文會被設置成這個object對象,name要執行的函數,次函數必須是content對象的屬性、
jQuery.proxy( function, context [, additionalArguments ] )
function為執行的函數,content為函數的上下文this值會被設置成這個object對象,additionalArguments任何數目的參數,傳遞給function
更詳細的用法參考:
http://www.css88.com/jqapi-1.9/jQuery.proxy/
現在讓我們一起來看實際例子:
var objPerson = { name: "obj", age: 32, test: function() { $("p").after("Name: " + this.name + "<br> Age: " + this.age); } } $("#btn").on("click", $.proxy(objPerson.test, objPerson))
點擊按鈕,輸出:Name:obj Age:32
objPerson.test表示上下文的方法,objPerson代表執行的上下文,例子中的this的上下文指的是objPerson
更具體的例子如:
var me = { type: "zombie", test: function(event) { /* Without proxy, `this` would refer to the event target */ /* use event.target to reference that element. */ var element = event.target; $(element).css("background-color", "red"); /* With proxy, `this` refers to the me object encapsulating */ /* this function. */ $("#log").append("Hello " + this.type + "<br>"); $("#test").unbind("click", this.test); } }; var you = { type: "person", test: function(event) { $("#log").append(this.type + " "); } }; /* execute you.test() in the context of the `you` object */ /* no matter where it is called */ /* i.e. the `this` keyword will refer to `you` */ var youClick = $.proxy(you.test, you); /* attach click handlers to #test */ $("#test") /* this === "zombie"; handler unbound after first click */ .on("click", $.proxy(me.test, me)) /* this === "person" */ .on("click", youClick) /* this === "zombie" */ .on("click", $.proxy(you.test, me)) /* this === "<button> element" */ .on("click", you.test);
結合以上說明,再寫一個綜合的例子,例如 js封裝一個ajax請求,代碼如下:
var t = { param: {}, url: "", type: "get", dataType: "json", ajaxOnly: true, contentType: 'application/x-www-form-urlencoded', /** * 取model數據 * @param {Function} onComplete 取完的回調函 * 傳入的第一個參數為model的數第二個數據為元數據,元數據為ajax下發時的ServerCode,Message等數 * @param {Function} onError 發生錯誤時的回調 * @param {Boolean} ajaxOnly 可選,默認為false當為true時只使用ajax調取數據 * @param {Boolean} scope 可選,設定回調函數this指向的對象 * @param {Function} onAbort 可選,但取消時會調用的函數 */ execute: function(onComplete, onError, ajaxOnly, scope) { var __onComplete = $.proxy(function(data) { var _data = data; if (typeof data == 'string') _data = JSON.parse(data); // @description 對獲取的數據做字段映射 var datamodel = typeof this.dataformat === 'function' ? this.dataformat(_data) : _data; if (this.onDataSuccess) this.onDataSuccess.call(this, datamodel, data); if (typeof onComplete === 'function') { onComplete.call(scope || this, datamodel, data); } }, this); var __onError = $.proxy(function(e) { if (typeof onError === 'function') { onError.call(scope || this, e); } }, this); this.sendRequest(__onComplete, __onError); }, sendRequest: function(success, error) { var params = _.clone(this.getParam() || {}); var crossDomain = { 'json': true, 'jsonp': true }; if (this.type == 'POST') { this.dataType = 'json'; } //jsonp與post互斥 $.ajax({ url: this.url, type: this.type, data: params, dataType: this.dataType, contentType: this.contentType, crossDomain: crossDomain[this.dataType], timeout: 50000, // xhrFields: { // withCredentials: true // }, success: function(res) { success && success(res); }, error: function(err) { error && error(err); } }); }, setParam: function(key, val) { if (typeof key === 'object') { _.extend(this.param, key); } else { this.param[key] = val; } }, removeParam: function(key) { delete this.param[key]; }, getParam: function() { return this.param; }, dataformat: function(data) { if (_.isString(data)) data = JSON.parse(data); if (data.data) return data.data; return data; }, onDataSuccess: function() {} }
調用封裝的方法:
function getData(url) { //設置參數 t.setParam({ "CurrentDestId": 7, "Platform":2, "ViewDestId":7 }); t.url=url; t.type="post"; //調用 t.execute(function(data){ var list=data.Tags; var temp=_.template($("#foodListTemp").html()); $("#list").html(temp({"dataTag":list})); },function(data){ alert("fail"); }); }
