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

 更新时间:2011年09月28日 00:33:29   作者:  
JavaScript对象与DOM对象进行绑定会遇到一个问题:如果被绑定的对象的方法中包含this关键字,当事件被触发时this指向的却是DOM对象,而不是之前的JS对象。
先来看看现象:
复制代码 代码如下:

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

相关文章

  • 一文详解JS私有属性的6种实现方式

    一文详解JS私有属性的6种实现方式

    class是创建对象的模版,由一系列属性和方法构成,用于表示对同一概念的数据和操作。有的属性和方法是对外的,但也有的是私有的。本文梳理了六种私有属性的实现方式,需要的可以参考一下
    2022-03-03
  • JavaScript实现给浮点数添加千分位逗号的多种方法

    JavaScript实现给浮点数添加千分位逗号的多种方法

    JavaScript 是一门强大的前端语言,在处理数值格式化时提供了多种方法,在开发过程中,我们经常需要将大数字格式化,使其更具可读性,例如,将 12000000.11 转换为 12,000,000.11,本文将详细介绍 JavaScript 中如何实现这种格式化,需要的朋友可以参考下
    2025-04-04
  • 在线游戏大家来找茬II

    在线游戏大家来找茬II

    在线游戏大家来找茬II...
    2006-09-09
  • JS使用正则表达式除去字符串中重复字符的方法

    JS使用正则表达式除去字符串中重复字符的方法

    这篇文章主要介绍了JS使用正则表达式除去字符串中重复字符的方法,以一个简单实例分析了JavaScript中正则过滤的相关使用技巧,需要的朋友可以参考下
    2015-11-11
  • JS实现的哈夫曼编码示例【原始版与修改版】

    JS实现的哈夫曼编码示例【原始版与修改版】

    这篇文章主要介绍了JS实现的哈夫曼编码,结合实例形式分析了基于JavaScript定义、使用哈夫曼树进行编码、解码等相关操作技巧,需要的朋友可以参考下
    2018-04-04
  • Javascript根据指定下标或对象删除数组元素

    Javascript根据指定下标或对象删除数组元素

    删除数组元素在工作中经常会用到,本文讲解一下Javascript根据下标删除数组元素的方法,需要了解的朋友可以参考下
    2012-12-12
  • 点击按钮弹出模态框的一系列操作代码实例

    点击按钮弹出模态框的一系列操作代码实例

    这篇文章主要介绍了js弹出模态框方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-03-03
  • jQuery与js实现颜色渐变的方法

    jQuery与js实现颜色渐变的方法

    这篇文章主要介绍了jQuery与js实现颜色渐变的方法,涉及javascript与jQuery的正则操作与数学运算相关技巧,需要的朋友可以参考下
    2016-12-12
  • Bootstrap实现前端登录页面带验证码功能完整示例

    Bootstrap实现前端登录页面带验证码功能完整示例

    这篇文章主要介绍了Bootstrap实现前端登录页面带验证码功能,结合完整实例形式分析了Bootstrap前端登录页面带验证码界面布局与功能实现相关操作技巧,需要的朋友可以参考下
    2020-03-03
  • JS比较两个数值的大小实例

    JS比较两个数值的大小实例

    下面小编就为大家带来一篇JS比较两个数值的大小实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-11-11

最新评论