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函数的第二个参数获取指定上下文中的DOM元素
May 19 Javascript
深入分析escape()、encodeURI()、encodeURIComponent()的区别及示例
Aug 04 Javascript
详解JavaScript基于面向对象之继承
Dec 13 Javascript
JSONP跨域请求实例详解
Jul 04 Javascript
Node.js 文件夹目录结构创建实例代码
Jul 08 Javascript
用file标签实现多图文件上传预览
Feb 14 Javascript
jQuery层叠选择器用法实例分析
Jun 28 jQuery
解决vue初始化项目时,一直卡在Project description上的问题
Oct 31 Javascript
es6数组的flat(),flatMap()函数用法实例分析
Apr 18 Javascript
只有 20 行的 JavaScript 模板引擎实例详解
May 11 Javascript
vue tab滚动到一定高度,固定在顶部,点击tab切换不同的内容操作
Jul 22 Javascript
原生JavaScript实现轮播图
Jan 10 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
如何提高MYSQL数据库的查询统计速度 select 索引应用
2007/04/11 PHP
php GD绘制24小时柱状图
2008/06/28 PHP
PHP获取栏目的所有子级和孙级栏目的ID号示例
2014/04/01 PHP
php5.4以上版本GBK编码下htmlspecialchars输出为空问题解决方法汇总
2015/04/03 PHP
Jquery乱码的一次解决过程 图解教程
2010/02/20 Javascript
jQuery EasyUI 开源插件套装 完全替代ExtJS
2010/03/24 Javascript
自制轻量级仿jQuery.boxy对话框插件代码
2010/10/26 Javascript
修改file按钮的默认样式实现代码
2013/04/23 Javascript
用js的for循环获取radio选中的值
2013/10/21 Javascript
button没写type=button会导致点击时提交
2014/03/06 Javascript
wap手机图片滑动切换特效无css3元素js脚本编写
2014/07/28 Javascript
JavaScript日期时间与时间戳的转换函数分享
2015/01/31 Javascript
用move.js库实现百叶窗特效
2017/02/08 Javascript
JavaScript之排序函数_动力节点Java学院整理
2017/06/30 Javascript
五步轻松实现JavaScript HTML时钟效果
2020/03/25 Javascript
JavaScript设计模式之单例模式原理与用法实例分析
2018/07/26 Javascript
js微信分享接口调用详解
2019/07/23 Javascript
vue 开发之路由配置方法详解
2019/12/02 Javascript
vue实现拖拽效果
2019/12/23 Javascript
JS如何实现封装列表右滑动删除收藏按钮
2020/07/23 Javascript
vue3.0自定义指令(drectives)知识点总结
2020/12/27 Vue.js
vue3.0 项目搭建和使用流程
2021/03/04 Vue.js
Python实现合并两个列表的方法分析
2018/05/28 Python
python实现祝福弹窗效果
2019/04/07 Python
解决Python计算矩阵乘向量,矩阵乘实数的一些小错误
2019/08/26 Python
python:动态路由的Flask程序代码
2019/11/22 Python
使用python去除图片白色像素的实例
2019/12/12 Python
解决paramiko执行命令超时的问题
2020/04/16 Python
python是怎么被发明的
2020/06/15 Python
css3实现一款模仿iphone样式的注册表单
2013/03/20 HTML / CSS
合伙经营协议书范本
2014/04/18 职场文书
酒店员工手册范本
2015/05/14 职场文书
红色故事汇观后感
2015/06/18 职场文书
2016高校自主招生自荐信范文
2016/01/28 职场文书
因个人工作失误检讨书
2019/06/21 职场文书
Redis超详细讲解高可用主从复制基础与哨兵模式方案
2022/04/07 Redis