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 相关文章推荐
div当滚动到页面顶部的时候固定在顶部实例代码
May 27 Javascript
node.js实现逐行读取文件内容的代码
Jun 27 Javascript
jquery实现个人中心导航菜单效果和美观都非常不错
Sep 02 Javascript
jquery图片倾斜层叠切换特效代码分享
Aug 27 Javascript
jQuery 判断是否包含在数组中Array[]的方法
Aug 03 Javascript
JS上传图片预览插件制作(兼容到IE6)
Aug 07 Javascript
easyui取消表单实时验证,提交时统一验证的简单实例
Nov 07 Javascript
js仿淘宝商品放大预览功能
Mar 15 Javascript
Vue的watch和computed方法的使用及区别介绍
Sep 06 Javascript
Vue在chrome44偶现点击子元素事件无法冒泡的解决方法
Dec 15 Javascript
Vue的状态管理vuex使用方法详解
Feb 05 Javascript
Vue和React有哪些区别
Sep 12 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
合作指挥官:孟斯克
2020/03/16 星际争霸
PHP脚本数据库功能详解(上)
2006/10/09 PHP
Laravel 5 学习笔记
2015/03/06 PHP
CodeIgniter生成静态页的方法
2016/05/17 PHP
Javascript中获取出错代码所在文件及行数的代码
2010/09/23 Javascript
javascript基础知识大全 便于大家学习,也便于我自己查看
2012/08/17 Javascript
基于js disabled=&quot;false&quot;不起作用的解决办法
2013/06/26 Javascript
JavaScript包装对象使用详解
2015/07/09 Javascript
基于JavaScript实现全屏透明遮罩div层锁屏效果
2016/01/26 Javascript
JS 事件绑定、事件监听、事件委托详细介绍
2016/09/28 Javascript
jquery利用json实现页面之间传值的实例解析
2016/12/12 Javascript
详解Html a标签中href和onclick用法、区别、优先级别
2017/01/16 Javascript
详解vue-cli中的ESlint配置文件eslintrc.js
2017/09/25 Javascript
vue项目总结之文件夹结构配置详解
2017/12/13 Javascript
Javascript网页抢红包外挂实现分享
2018/01/11 Javascript
js实现贪吃蛇游戏(简易版)
2020/09/29 Javascript
[02:06]2018完美世界全国高校联赛秋季赛开始报名(附彩蛋)
2018/09/03 DOTA
[原创]教女朋友学Python(一)运行环境搭建
2017/11/29 Python
Python使用Matplotlib实现雨点图动画效果的方法
2017/12/23 Python
Python实现PS滤镜碎片特效功能示例
2018/01/24 Python
python执行系统命令后获取返回值的几种方式集合
2018/05/12 Python
python3 json数据格式的转换(dumps/loads的使用、dict to str/str to dict、json字符串/字典的相互转换)
2019/04/01 Python
python 二维矩阵转三维矩阵示例
2019/11/30 Python
python实现用户名密码校验
2020/03/18 Python
使用keras实现BiLSTM+CNN+CRF文字标记NER
2020/06/29 Python
如何使用Python调整图像大小
2020/09/26 Python
pandas map(),apply(),applymap()区别解析
2021/02/24 Python
欧洲最大的婴幼儿服装及内衣公司:Petit Bateau(小帆船)
2016/08/16 全球购物
马来西亚最大的电器网站:Senheng
2017/10/13 全球购物
美国在线鞋类零售商:LifeStride
2019/06/09 全球购物
软件测试常见笔试题
2012/02/04 面试题
EJB与JAVA BEAN的区别
2016/08/29 面试题
大学专科自荐信
2014/06/17 职场文书
给妈妈洗脚活动方案
2014/08/16 职场文书
2016教师廉洁教育心得体会
2016/01/13 职场文书
动画「进击的巨人」第86话播出感谢绘公开
2022/03/21 日漫