JavaScript call apply使用 JavaScript对象的方法绑定到DOM事件后this指向问题


Posted in Javascript onSeptember 28, 2011

先来看看现象:

<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>

当单击DIV后,弹出框显示undefined。
原因是当DOM对象响应单击事件后,事件方法中的this关键字指向的是DOM对象,此时DOM对象没有a属性,所以弹出undefined。
而程序员本意是响应事件方法中this指向的是classA的对象a,如何才能达到此目的?这就需要使用到call或apply方法。
下面再来熟悉下call方法:
摘要:
function.call(thisobj, args…)
参数:
thisobj

调用function的对象。在函数主体中,thisobj是关键字this的值。
args…

任意多个参数,这些参数将传递给函数function。
返回值:
调用函数function的返回值。
抛出:
TypeError

如果调用该函数的对象不是函数,则抛出该异常。
描述:
call()将指定的函数function作为对象thisobj的方法来调用,把参数列表中thisobj后的参数传递给它,返回值是调用函数后的返回值。在函数体内,关键字this引用thisobj对象。
如果将指定数组作为传递给函数的参数,请使用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方法,该方法包含三个参数:fun、obj、arg,分别是“要执行的方法”、“fun中this需要指向的对象”、“传入fun中的参数”。该方法返回一个匿名方法。
匿名方法负责执行fun方法,同时将fun中的this指向obj,并使用作为arg传入参数,处理结果返回。
当程序执行走到第15行调用createDele方法,传入对象的方法和对象本身,createDele接收参数后返回一个匿名方法,this.clickDele被设置成为返回的匿名方法,16行代码将this.clickDele(匿名方法)绑定到DOM事件上,程序执行完毕,点击DOM(DIV)触发匿名方法,些时匿名方法中fun为之前传入的this.click(即:方法a.click),obj为之前传入的this(即:对象a),所以此时使用call方法使得this.click(即:方法a.click)中的this指向obj(即:对象a),最终弹出结果为1。结果正确,达到了程序的本意。
回顾匿名方法多少会让人感到有些怪异:调用匿名方法时fun为什么会是this.click(即:方法a.click)、obj什么为是this(即:对象a)。这个问题就需要用JavaScript的闭包来解释了,这里暂不介绍闭包,后面会有介绍JavaScript闭包的文章发表,欢迎有兴趣的朋友持续关注!
不管各位看官信还是不信,反正道理和程序是没有问题的!:)
Javascript 相关文章推荐
jquery div 居中技巧应用介绍
Nov 24 Javascript
HTML复选框和单选框 checkbox和radio事件介绍
Dec 12 Javascript
jQuery输入城市查看地图使用介绍
May 08 Javascript
JQuery实现表格中相同单元格合并示例代码
Jun 26 Javascript
jquery的ajax简单结构示例代码
Feb 17 Javascript
javascript学习笔记(三)BOM和DOM详解
Sep 30 Javascript
全面了解JavaScirpt 的垃圾(garbage collection)回收机制
Jul 11 Javascript
Javascript 引擎工作机制详解
Nov 30 Javascript
Bootstrap select实现下拉框多选效果
Dec 23 Javascript
js CSS3实现卡牌旋转切换效果
Jul 04 Javascript
详解如何在vue项目中使用layui框架及采坑
May 05 Javascript
JavaScript从原型到原型链深入理解
Jun 03 Javascript
javascript权威指南 学习笔记之变量作用域分享
Sep 28 #Javascript
关于setInterval、setTimeout在jQuery中的使用注意事项
Sep 28 #Javascript
jQuery Ajax 仿AjaxPro.Utility.RegisterTypeForAjax辅助方法
Sep 27 #Javascript
Ext.get() 和 Ext.query()组合使用实现最灵活的取元素方式
Sep 26 #Javascript
一个挺有意思的Javascript小问题说明
Sep 26 #Javascript
Jquery之Ajax运用 学习运用篇
Sep 26 #Javascript
jQuery+CSS 实现随滚动条增减的汽水瓶中的液体效果
Sep 26 #Javascript
You might like
php cookie 登录验证示例代码
2009/03/16 PHP
Yii使用smsto短信接口的函数demo示例
2016/07/13 PHP
PHP PDOStatement::setFetchMode讲解
2019/02/03 PHP
javascript读取RSS数据
2007/01/20 Javascript
在jQuery1.5中使用deferred对象 着放大镜看Promise
2011/03/12 Javascript
Javascript 异步加载详解(浏览器在javascript的加载方式)
2012/05/20 Javascript
使用jQuery Ajax功能时需要注意的一个问题(内存溢出)
2012/05/30 Javascript
js导入导出excel(实例代码)
2013/11/25 Javascript
jQuery多个input求和的实现方法
2015/02/12 Javascript
JS实现自适应高度表单文本框的方法
2015/02/25 Javascript
jQuery实现伸展与合拢panel的方法
2015/04/30 Javascript
学做Bootstrap的第一个页面
2016/05/15 HTML / CSS
js 上传文件预览的简单实例
2016/08/16 Javascript
聊聊JavaScript如何实现继承及特点
2017/04/07 Javascript
利用jQuery解析获取JSON数据
2017/04/08 jQuery
详解JavaScript调用栈、尾递归和手动优化
2017/06/03 Javascript
解决vue使用vant轮播组件swipe + flex时文字抖动问题
2021/01/07 Vue.js
[09:34]2018DOTA2国际邀请赛寻真——永不放弃的iG
2018/08/14 DOTA
对于Python中线程问题的简单讲解
2015/04/03 Python
浅谈django中的认证与登录
2016/10/31 Python
简单谈谈python中的多进程
2016/11/06 Python
浅析Python pandas模块输出每行中间省略号问题
2018/07/03 Python
Django框架设置cookies与获取cookies操作详解
2019/05/27 Python
Lacoste澳大利亚官网:服装、鞋类及配饰
2018/11/14 全球购物
汽车驾驶求职信
2013/10/25 职场文书
国家助学金获奖感言
2014/01/31 职场文书
企业办公室主任岗位职责
2014/02/19 职场文书
代办出身证明书
2014/10/21 职场文书
2014年社区矫正工作总结
2014/11/18 职场文书
中学生综合素质自我评价
2015/03/06 职场文书
工厂门卫岗位职责
2015/04/13 职场文书
2015年乡镇卫生院工作总结
2015/04/22 职场文书
演讲比赛主持词
2015/06/29 职场文书
php 防护xss,PHP的防御XSS注入的终极解决方案
2021/04/01 PHP
SqlServer 垂直分表(减少程序改动)
2021/04/16 SQL Server
详解CSS中的特指度和层叠问题
2021/07/15 HTML / CSS