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 学习点滴记录
Apr 24 Javascript
js 效率组装字符串 StringBuffer
Dec 23 Javascript
在JS中解析HTML字符串示例代码
Apr 16 Javascript
Javascript MVC框架Backbone.js详解
Sep 18 Javascript
超赞的动手创建JavaScript框架的详细教程
Jun 30 Javascript
JavaScript实现点击按钮就复制当前网址
Dec 14 Javascript
jQuery无刷新上传之uploadify简单代码
Jan 17 Javascript
BOM之navigator对象和用户代理检测
Feb 10 Javascript
jQuery插件zTree实现更新根节点中第i个节点名称的方法示例
Mar 08 Javascript
原生JS实现层叠轮播图
May 17 Javascript
webpack 2的react开发配置实例代码
Jul 28 Javascript
详解在HTTPS 项目中使用百度地图 API
Apr 26 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
人尽可用的Windows技巧小贴士之下篇
2007/03/22 PHP
php下实现折线图效果的代码
2007/04/28 PHP
PHP目录函数实现创建、读取目录教程实例
2011/01/13 PHP
PHP中mysqli_affected_rows作用行数返回值分析
2014/12/26 PHP
php在数据库抽象层简单使用PDO的方法
2015/11/03 PHP
laravel项目利用twemproxy部署redis集群的完整步骤
2018/05/11 PHP
Yii2压缩PHP中模板代码的输出问题
2018/08/28 PHP
jquery 锁定弹出层实现代码
2010/02/23 Javascript
jquery随机展示头像代码
2011/12/21 Javascript
javascript设置金额样式转换保留两位小数示例代码
2013/12/04 Javascript
JavaScript实现常用二级省市级联下拉列表的方法
2015/03/25 Javascript
js代码实现随机颜色的小方块
2015/07/30 Javascript
JavaScript下的时间格式处理函数Date.prototype.format
2016/01/27 Javascript
JavaScript中原型链存在的问题解析
2016/09/25 Javascript
SpringMVC+bootstrap table实例详解
2017/06/02 Javascript
推荐10款扩展Web表单的JS插件
2017/12/25 Javascript
JS实现中英文混合文字溢出友好截取功能
2018/08/06 Javascript
vue移动端微信授权登录插件封装的实例
2018/08/28 Javascript
JavaScript基于遍历操作实现对象深拷贝功能示例
2019/03/05 Javascript
vue2.0基于vue-cli+element-ui制作树形treeTable
2019/04/30 Javascript
关于Layui Table隐藏列问题
2019/09/16 Javascript
layui 中select下拉change事件失效的解决方法
2019/09/20 Javascript
js面向对象之实现淘宝放大镜
2020/01/15 Javascript
vue 实现element-ui中的加载中状态
2020/11/11 Javascript
python 示例分享---逻辑推理编程解决八皇后
2014/07/20 Python
Python及Django框架生成二维码的方法分析
2018/01/31 Python
Python实现简单求解给定整数的质因数算法示例
2018/03/25 Python
Python3环境安装Scrapy爬虫框架过程及常见错误
2019/07/12 Python
python 利用jinja2模板生成html代码实例
2019/10/10 Python
Flask框架 CSRF 保护实现方法详解
2019/10/30 Python
OpenCV python sklearn随机超参数搜索的实现
2020/01/17 Python
人事行政主管岗位职责
2013/12/22 职场文书
商务会议邀请函
2014/01/09 职场文书
鲜花方阵解说词
2014/02/13 职场文书
焦裕禄精神心得体会
2014/09/02 职场文书
党的群众路线教育实践活动个人整改措施范文
2014/11/04 职场文书