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 相关文章推荐
JavaScript的面向对象(二)
Nov 09 Javascript
javascript 支持ie和firefox杰奇翻页函数
Jul 22 Javascript
JQuery扩展插件Validate 1 基本使用方法并打包下载
Sep 05 Javascript
Javascript的时间戳和php的时间戳转换注意事项
Apr 12 Javascript
获取3个数组不重复的值的具体实现
Dec 30 Javascript
jquery插件corner实现圆角边框的方法
Mar 09 Javascript
jQuery验证插件validation使用指南
Apr 21 Javascript
jquery实现仿新浪微博带动画效果弹出层代码(可关闭、可拖动)
Oct 12 Javascript
JavaScript制作颜色反转小游戏
Sep 25 Javascript
用headjs来管理和加载js 提高网站加载速度
Nov 29 Javascript
VUE DOM加载后执行自定义事件的方法
Sep 07 Javascript
基于Vue el-autocomplete 实现类似百度搜索框功能
Oct 25 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文件下载类
2006/12/06 PHP
PHP 第二节 数据类型之数组
2012/04/28 PHP
利用PHP命令行模式采集股票趋势信息
2016/08/09 PHP
php中pcntl_fork创建子进程的方法实例
2019/03/14 PHP
YII2框架中behavior行为的理解与使用方法示例
2020/03/13 PHP
javascript编程起步(第四课)
2007/02/27 Javascript
响应鼠标变换表格背景或者颜色的代码
2009/03/30 Javascript
js cookies实现简单统计访问次数
2009/11/24 Javascript
JQuery调webservice实现邮箱验证(检测是否可用)
2013/05/21 Javascript
5分钟理解JavaScript中this用法分享
2013/11/09 Javascript
JS的参数传递示例介绍
2014/02/08 Javascript
如何让你的Lightbox支持滚轮缩放及Base64图片
2014/12/04 Javascript
jquery使用hide方法隐藏指定id的元素
2015/03/30 Javascript
Vue上传组件vue Simple Uploader的用法示例
2017/08/25 Javascript
Vue 组件(component)教程之实现精美的日历方法示例
2018/01/08 Javascript
如何用RxJS实现Redux Form
2018/12/29 Javascript
微信小程序数据统计和错误统计的实现方法
2019/06/26 Javascript
[40:56]2018DOTA2亚洲邀请赛 3.31 小组赛 A组 Liquid vs TNC
2018/04/01 DOTA
python进阶教程之循环对象
2014/08/30 Python
Python3.2模拟实现webqq登录
2016/02/15 Python
详解Python中的type和object
2018/08/15 Python
influx+grafana自定义python采集数据和一些坑的总结
2018/09/17 Python
Django objects的查询结果转化为json的三种方式的方法
2018/11/07 Python
解决python中无法自动补全代码的问题
2018/12/04 Python
python计算阶乘和的方法(1!+2!+3!+...+n!)
2019/02/01 Python
python使用 cx_Oracle 模块进行查询操作示例
2019/11/28 Python
Python中pass的作用与使用教程
2020/11/13 Python
集世界奢侈品和设计师品牌的意大利精品买手店:Tessabit
2019/08/17 全球购物
升旗仪式主持词
2014/03/19 职场文书
医学生毕业自我鉴定
2014/03/26 职场文书
小学生节约用水倡议书
2014/05/15 职场文书
大学生安全教育心得体会
2016/01/15 职场文书
python数据分析之用sklearn预测糖尿病
2021/04/22 Python
Spring Bean的实例化之属性注入源码剖析过程
2021/06/13 Java/Android
《帝国时代4》赛季预告 新增内容编译器可创造地图
2022/04/03 其他游戏
mysql查看表结构的三种方法总结
2022/07/07 MySQL