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操作select方法大全[新增、修改、删除、选中、清空、判断存在等]
Sep 26 Javascript
Javascript var变量隐式声明方法
Oct 19 Javascript
去掉gridPanel表头全选框的小例子
Jul 18 Javascript
以JSON形式将JS中Array对象数组传至后台的方法
Jan 06 Javascript
js实现按钮加背景图片常用方法
Nov 01 Javascript
jQuery的图片滑块焦点图插件整理推荐
Dec 07 Javascript
JS操作COOKIE实现备忘记录的方法
Apr 01 Javascript
javascript创建对象的几种模式介绍
May 06 Javascript
axios基本入门用法教程
Mar 25 Javascript
小程序开发中如何使用async-await并封装公共异步请求的方法
Jan 20 Javascript
JavaScript JSON数据处理全集(小结)
Aug 15 Javascript
Vue3实现简易音乐播放器组件
Aug 14 Vue.js
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
2006/10/09 PHP
二招解决php乱码问题
2012/03/25 PHP
Linux系统递归生成目录中文件的md5的方法
2015/06/29 PHP
简单谈谈PHP中的include、include_once、require以及require_once语句
2016/04/23 PHP
Windows上php5.6操作mongodb数据库示例【配置、连接、获取实例】
2019/02/13 PHP
PHP模糊查询技术实例分析【附源码下载】
2019/03/07 PHP
JavaScript 常见对象类创建代码与优缺点分析
2009/12/07 Javascript
javascript相等运算符与等同运算符详细介绍
2013/11/09 Javascript
关于jquery中全局函数each使用介绍
2013/12/10 Javascript
JavaSript中变量的作用域闭包的深入理解
2014/05/12 Javascript
JavaScript对Cookie进行读写操作实例
2015/07/25 Javascript
JS函数定义方式的区别介绍
2016/03/22 Javascript
Vue.js中数组变动的检测详解
2016/10/12 Javascript
bootstrap 设置checkbox部分选中效果
2017/04/20 Javascript
基于JS实现网页中的选项卡(两种方法)
2017/06/16 Javascript
JS实现移动端整屏滑动的实例代码
2017/11/10 Javascript
详解vuex之store拆分即多模块状态管理(modules)篇
2018/11/13 Javascript
vue+element-ui+axios实现图片上传
2019/08/20 Javascript
Vue3配置axios跨域实现过程解析
2020/11/25 Vue.js
[01:18:35]DOTA2-DPC中国联赛 正赛 Elephant vs LBZS BO3 第一场 1月29日
2021/03/11 DOTA
Python中Django发送带图片和附件的邮件
2017/03/31 Python
Python标准库sched模块使用指南
2017/07/06 Python
Python序列化基础知识(json/pickle)
2017/10/19 Python
python实现聚类算法原理
2018/02/12 Python
Python3数据库操作包pymysql的操作方法
2018/07/16 Python
对Python中实现两个数的值交换的集中方法详解
2019/01/11 Python
Django实现celery定时任务过程解析
2020/04/21 Python
将pycharm配置为matlab或者spyder的用法说明
2020/06/08 Python
OnePlus加拿大官网:中国国际化手机品牌
2020/10/13 全球购物
为什么如下的代码int a=100,b=100;long int c=a * b;不能工作
2013/11/29 面试题
JAVA招聘远程笔试题
2015/07/23 面试题
运动会闭幕式解说词
2014/02/21 职场文书
信访工作个人总结
2015/03/03 职场文书
2015年乡镇纪委工作总结
2015/05/26 职场文书
2016基督教会圣诞节开幕词
2016/03/04 职场文书
MySql子查询IN的执行和优化的实现
2021/08/02 MySQL