JavaScript call apply使用 JavaScript對(duì)象的方法綁定到DOM事件后this指向問(wèn)題
<html>
<head>
<title>apply_and_call</title>
</head>
<body onload="init()">
<div id="testDiv" style="position: absolute; border: 1px solid gray; width:100px; height: 100px"></div>
<script type="text/javascript">
function init() {
var el = document.getElementById("testDiv");
var a = new classA(el);
}
function classA(el) {
this.a = 1;
this.container = el;
//綁定單擊事件
this.container.onclick = this.click;
}
classA.prototype = {
click:function() {
alert(this.a);
}
}
</script>
</body>
</html>
當(dāng)單擊DIV后,彈出框顯示undefined。
原因是當(dāng)DOM對(duì)象響應(yīng)單擊事件后,事件方法中的this關(guān)鍵字指向的是DOM對(duì)象,此時(shí)DOM對(duì)象沒(méi)有a屬性,所以彈出undefined。
而程序員本意是響應(yīng)事件方法中this指向的是classA的對(duì)象a,如何才能達(dá)到此目的?這就需要使用到call或apply方法。
下面再來(lái)熟悉下call方法:
摘要:
function.call(thisobj, args…)
參數(shù):
thisobj
調(diào)用function的對(duì)象。在函數(shù)主體中,thisobj是關(guān)鍵字this的值。
args…
任意多個(gè)參數(shù),這些參數(shù)將傳遞給函數(shù)function。
返回值:
調(diào)用函數(shù)function的返回值。
拋出:
TypeError
如果調(diào)用該函數(shù)的對(duì)象不是函數(shù),則拋出該異常。
描述:
call()將指定的函數(shù)function作為對(duì)象thisobj的方法來(lái)調(diào)用,把參數(shù)列表中thisobj后的參數(shù)傳遞給它,返回值是調(diào)用函數(shù)后的返回值。在函數(shù)體內(nèi),關(guān)鍵字this引用thisobj對(duì)象。
如果將指定數(shù)組作為傳遞給函數(shù)的參數(shù),請(qǐng)使用Function.apply()方法。
熟悉call()方法后,將代碼1修改如下:
代碼2:
<html>
<head>
<title>apply_and_call</title>
</head>
<body onload="init()">
<div id="testDiv" style="position: absolute; border: 1px solid gray; width:100px; height: 100px"></div>
<script type="text/javascript">
function init() {
var el = document.getElementById("testDiv");
var a = new classA(el);
}
function classA(el) {
this.t = 1;
this.clickDele = createDele(this.click, this);
el.onclick = this.clickDele;
}
classA.prototype = {
click:function() {
alert(this.t);
}
}
function createDele(fun, obj, arg) {
return function() {
return fun.call(obj, arg);
}
}
</script>
</body>
</html>
代碼2 25行:主要添加了createDele方法,該方法包含三個(gè)參數(shù):fun、obj、arg,分別是“要執(zhí)行的方法”、“fun中this需要指向的對(duì)象”、“傳入fun中的參數(shù)”。該方法返回一個(gè)匿名方法。
匿名方法負(fù)責(zé)執(zhí)行fun方法,同時(shí)將fun中的this指向obj,并使用作為arg傳入?yún)?shù),處理結(jié)果返回。
當(dāng)程序執(zhí)行走到第15行調(diào)用createDele方法,傳入對(duì)象的方法和對(duì)象本身,createDele接收參數(shù)后返回一個(gè)匿名方法,this.clickDele被設(shè)置成為返回的匿名方法,16行代碼將this.clickDele(匿名方法)綁定到DOM事件上,程序執(zhí)行完畢,點(diǎn)擊DOM(DIV)觸發(fā)匿名方法,些時(shí)匿名方法中fun為之前傳入的this.click(即:方法a.click),obj為之前傳入的this(即:對(duì)象a),所以此時(shí)使用call方法使得this.click(即:方法a.click)中的this指向obj(即:對(duì)象a),最終彈出結(jié)果為1。結(jié)果正確,達(dá)到了程序的本意。
回顧匿名方法多少會(huì)讓人感到有些怪異:調(diào)用匿名方法時(shí)fun為什么會(huì)是this.click(即:方法a.click)、obj什么為是this(即:對(duì)象a)。這個(gè)問(wèn)題就需要用JavaScript的閉包來(lái)解釋了,這里暫不介紹閉包,后面會(huì)有介紹JavaScript閉包的文章發(fā)表,歡迎有興趣的朋友持續(xù)關(guān)注!
不管各位看官信還是不信,反正道理和程序是沒(méi)有問(wèn)題的?。海?
相關(guān)文章
基于Javascript實(shí)現(xiàn)彈出頁(yè)面效果
彈出層效果是一個(gè)很實(shí)用的功能,很多網(wǎng)站都采用了這種方式實(shí)現(xiàn)登錄和注冊(cè),下面小編通過(guò)本文給大家分享具體實(shí)現(xiàn)代碼,對(duì)js彈出頁(yè)面效果相關(guān)知識(shí)感興趣的朋友一起學(xué)習(xí)吧2016-01-01微信小程序與公眾號(hào)卡券/會(huì)員打通的問(wèn)題
這篇文章主要介紹了微信小程序與公眾號(hào)卡券/會(huì)員打通的問(wèn)題,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07javascript實(shí)現(xiàn)網(wǎng)頁(yè)子頁(yè)面遍歷回調(diào)的方法(涉及 window.frames、遞歸函數(shù)、函數(shù)上下文)
這篇文章主要介紹了javascript實(shí)現(xiàn)網(wǎng)頁(yè)子頁(yè)面遍歷回調(diào)的方法(涉及 window.frames、遞歸函數(shù)、函數(shù)上下文),涉及javascript回調(diào)、遍歷等實(shí)現(xiàn)技巧,需要的朋友可以參考下2015-07-07JS實(shí)現(xiàn)將二維數(shù)組轉(zhuǎn)為json格式字符串操作示例
這篇文章主要介紹了JS實(shí)現(xiàn)將二維數(shù)組轉(zhuǎn)為json格式字符串操作,涉及javascript數(shù)組遍歷、拼接、轉(zhuǎn)換等相關(guān)操作技巧,需要的朋友可以參考下2018-07-07ES6(ECMAScript 6)新特性之模板字符串用法分析
這篇文章主要介紹了ES6(ECMAScript 6)新特性之模板字符串用法,簡(jiǎn)單介紹了ES6模板字符串的概念、功能并結(jié)合實(shí)例形式分析了ES6模板字符串的用法,需要的朋友可以參考下2017-04-04JS獲取屏幕,瀏覽器窗口大小,網(wǎng)頁(yè)高度寬度(實(shí)現(xiàn)代碼)
本篇文章主要介紹了JS獲取屏幕,瀏覽器窗口大小,網(wǎng)頁(yè)高度寬度的實(shí)現(xiàn)代碼。需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助2013-12-12基于JavaScript實(shí)現(xiàn)簡(jiǎn)單掃雷游戲
這篇文章主要介紹了基于JavaScript實(shí)現(xiàn)簡(jiǎn)單掃雷游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-01-01