色尼玛亚洲综合影院,亚洲3atv精品一区二区三区,麻豆freexxxx性91精品,欧美在线91

jQuery AJAX回調(diào)函數(shù)this指向問題

如在全局作用域調(diào)用一個(gè)含this的對(duì)象,此時(shí)當(dāng)前對(duì)象的this指向的是window。為了讓this的指向符合自己的意愿,JavaScript提供了兩個(gè)方法用以改變this的指向,它們是call和apply,當(dāng)然也有利用閉包來實(shí)現(xiàn)的方法。本文通過一個(gè)例子來說明這些問題。

先看一段演示代碼,這代碼只供演示用,沒有實(shí)際意義。

復(fù)制代碼 代碼如下:
//一個(gè)沒有實(shí)際意義的socket連接對(duì)象
var socket =
{
connect: function(host, port)
{
alert('Connecting socket server,host:' + host + ',port:' + port);
}
};
//一個(gè)即時(shí)通訊類,其中connect方法還將作為AJAX回調(diào)函數(shù)被調(diào)用
function classIm()
{
this.host = '192.168.1.28';
this.port = '8080';
this.connect = function(data)
{
socket.connect(this.host, this.port);
};
}
//實(shí)例化即時(shí)通訊類
var IM = new classIm();
//AJAX請(qǐng)求,這里假設(shè)要打開socket連接首先要通過WEB得知用戶WEB登錄成功
$.get('CheckWebLogin.ASPx', IM.connect);
運(yùn)行上面的例子,你將看到彈出的host與port都是undefined,那是因?yàn)榛卣{(diào)函數(shù)的this不是指向IM對(duì)象,而是jQuery的AJAX配置對(duì)象ajaxSettings。在jQuery內(nèi)部是用s.success代替?zhèn)魅氲幕卣{(diào)函數(shù)去執(zhí)行的,而success的調(diào)用對(duì)象就是s,即下面ajaxSettings對(duì)象的縮寫。

ajaxSettings:
{
url: location.href,
global: true,
type: "GET",
contentType: "application/x-www-form-urlencoded",
processData: true,
async: true
}

為了證明這一點(diǎn),你可以這樣修改代碼測(cè)試一下,你將看到是url、global、type、contentType等對(duì)象的屬性名稱:
復(fù)制代碼 代碼如下:
this.connect = function(data)
{
for (var key in this)
{
alert(key);
}
}


現(xiàn)在了解了問題所在,接下來想辦法解決這個(gè)問題。其實(shí)我們的目的是希望AJAX回調(diào)函數(shù)代碼socket.connect(this.host, this.port)中的this指向類classIm的實(shí)例對(duì)象IM,或者說是想socket.connect()方法能得到正確的參數(shù)值吧。為了得到預(yù)期的AJAX回調(diào)函數(shù)執(zhí)行結(jié)果,我分析了大致有下面幾種方法:

方法一

直接傳對(duì)象的正確引用而非this指針,或叫對(duì)象實(shí)傳。這是最常見的做法,即在類實(shí)例化時(shí)用一個(gè)變量存儲(chǔ)對(duì)當(dāng)前對(duì)象的引用,在后面的方法中直接使用此變量代替this的使用。注意:這種方法并沒有真正改變this的指向。演示代碼如下,注意對(duì)比前后兩次代碼的區(qū)別,我也特別高亮顯示差異部分代碼。
復(fù)制代碼 代碼如下:
var socket =
{
connect: function(host, port)
{
alert('Connecting socket server,host:' + host + ',port:' + port);
}
};
function classIm()
{
var self = this;
this.host = '192.168.1.28';
this.port = '8080';
this.connect = function(data)
{
socket.connect(self.host, self.port);
};
}
var IM = new classIm();
$.get('CheckWebLogin.ASPx', IM.connect);

方法二

使用apply加閉包實(shí)現(xiàn)真正改變this的指向。下面方法把函數(shù)調(diào)用時(shí)的this對(duì)象存到一個(gè)臨時(shí)變量_method,然后又利用閉包把它傳給返回的function對(duì)象,在這個(gè)返回的function中使用apply把調(diào)用時(shí)對(duì)象的this替換為目標(biāo)對(duì)象thisObj。這種方法是很多JavaScript框架的做法,而且下面這個(gè)Function原型方法正是我從prototype框架精簡(jiǎn)而來。注意我是先給Function原型加了Apply方法,這個(gè)Apply不是腳本內(nèi)置的apply,是我自定義的,如果你喜歡可以定個(gè)別的名字。
復(fù)制代碼 代碼如下:
/**
* 改變jQuery AJAX回調(diào)函數(shù)this指針指向
* @param {Object} thisObj 要替換當(dāng)前this指針的對(duì)象
* @return {Function} function(data){}
*/
Function.prototype.Apply = function(thisObj)
{
var _method = this;
return function(data)
{
return _method.apply(thisObj,[data]);
};
}
var socket =
{
connect: function(host, port)
{
alert('Connecting socket server,host:' + host + ',port:' + port);
}
};
function classIm()
{
this.host = '192.168.1.28';
this.port = '8080';
this.connect = function(data)
{
socket.connect(this.host, this.port);
};
}
var IM = new classIm();
$.get('CheckWebLogin.ASPx', IM.connect.Apply(IM));

方法三

在匿名回調(diào)函數(shù)中再調(diào)用實(shí)際的回調(diào)處理函數(shù)。這種方法雖然可以解決同樣的問題的,但是代碼有點(diǎn)長和多余,實(shí)際開發(fā)中是不建議這樣做的。這種方法是保證了調(diào)用connect方法的對(duì)象還是IM對(duì)象,從而保證了this指向還是IM對(duì)象。代碼如下:
復(fù)制代碼 代碼如下:
$.get('CheckWebLogin.ASPx', function(data){IM.connect(data)});

JavaScript技術(shù)jQuery AJAX回調(diào)函數(shù)this指向問題,轉(zhuǎn)載需保留來源!

鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請(qǐng)第一時(shí)間聯(lián)系我們修改或刪除,多謝。

主站蜘蛛池模板: 凉山| 股票| 蓬安县| 平乡县| 建宁县| 青川县| 龙里县| 二手房| 彭水| 伊宁市| 井研县| 许昌县| 侯马市| 铁岭市| 个旧市| 边坝县| 抚州市| 长垣县| 平利县| 施甸县| 吴忠市| 德令哈市| 南华县| 赤水市| 高台县| 龙井市| 固镇县| 万年县| 温泉县| 洪洞县| 长武县| 宜州市| 丰宁| 当涂县| 永城市| 兴业县| 宜良县| 隆林| 大宁县| 平潭县| 三门县|