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

所属分类: 网络编程 / JavaScript 阅读数: 1185
收藏 0 赞 0 分享
先来看看现象:
复制代码 代码如下:

<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闭包的文章发表,欢迎有兴趣的朋友持续关注!
不管各位看官信还是不信,反正道理和程序是没有问题的!:)
更多精彩内容其他人还在看

基于jquery封装的一个js分页

基于jquery封装的一个js分页代码,需要的朋友可以参考下。
收藏 0 赞 0 分享

关于js datetime的那点事

关于js datetime的一些使用经验分享,想要了解datetime日期操作的朋友可以参考下。
收藏 0 赞 0 分享

js 关于=+与+=日期函数使用说明(赋值运算符)

js 关于=+与+=日期函数使用说明(赋值运算符),可以看下,就是一些运算符的使用,看哪个更适合你。
收藏 0 赞 0 分享

JS 操作符整理[推荐收藏]

JS 操作符主要包括算术运算符,赋值运算符,比较(关系)运算符,逻辑运算符,串符(连接作用),条件运算符等
收藏 0 赞 0 分享

让html的text输入框只能输入数字和1个小数点(0-59之间可改)

今天有同事需要这个功能,主要是限制用户输入不符合规范的数字与小数点导致不好计算价格问题,特整理了下面的代码,需要的朋友可以参考下。
收藏 0 赞 0 分享

Jquery 获取checkbox的checked问题

这个郁闷了,今天写这个功能的时候发现了问题,上网找了好多资料对照,更加纠结
收藏 0 赞 0 分享

jQuery EasyUI API 中文文档 - DataGrid数据表格

jQuery EasyUI API 中文文档 - DataGrid数据表格使用说明,需要的朋友可以参考下。
收藏 0 赞 0 分享

jQuery EasyUI API 中文文档 - PropertyGrid属性表格

jQuery EasyUI API 中文文档 - PropertyGrid属性表格使用介绍,需要的朋友可以参考下。
收藏 0 赞 0 分享

20款效果非常棒的 jQuery 插件小结分享

这篇文章向大家推荐20款效果非常棒的 jQuery 插件。jQuery 是一个非常优秀的JavaScript库,它简化了 HTML 文档遍历,事件处理,动画以及 Ajax 交互,同时也改变了很多人编写 JavaScript 代码的方式
收藏 0 赞 0 分享

基于Jquery插件开发之图片放大镜效果(仿淘宝)

公司某个网站,需要实现图片预览效果,并能像淘宝一样实现局部分大,使用jquery的朋友可以参考下。
收藏 0 赞 0 分享
查看更多