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 Ajax学习实例3 向WebService发出请求,调用方法返回数据
Mar 16 Javascript
js输出列表实现代码
Sep 12 Javascript
JavaScript打印iframe内容示例代码
Aug 20 Javascript
js使下拉列表框可编辑不止是选择
Dec 12 Javascript
js生成缩略图后上传并利用canvas重绘
May 15 Javascript
javascript中数组array及string的方法总结
Nov 28 Javascript
JavaScript获取表格(table)当前行的值、删除行、增加行
Jul 03 Javascript
浅谈jquery的html方法里包含特殊字符的处理
Nov 30 Javascript
微信小程序 下拉列表的实现实例代码
Mar 08 Javascript
vuex的使用及持久化state的方式详解
Jan 23 Javascript
vue之组件内监控$store中定义变量的变化详解
Nov 08 Javascript
解决Vue使用bus总线时,第一次路由跳转时数据没成功传递问题
Jul 28 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
初级的用php写的采集程序
2007/03/16 PHP
PHP的消息通信机制测试实例
2016/11/10 PHP
jQuery get和post 方法传值注意事项
2009/11/03 Javascript
jquery-easyui关闭tab自动切换到前一个tab
2010/07/29 Javascript
document.getElementById的简写方式(获取id对象的简略写法)
2010/09/10 Javascript
使用jQuery内容过滤选择器选择元素实例讲解
2013/04/18 Javascript
设置jsf的选择框h:selectOneMenu为不可编辑状态的方法
2014/01/07 Javascript
js调用iframe实现打印页面内容的方法
2014/03/04 Javascript
zepto.js中tap事件阻止冒泡的实现方法
2015/02/12 Javascript
javascript实现滚动效果的数字时钟实例
2016/07/21 Javascript
angularjs实现文字上下无缝滚动特效代码
2016/09/04 Javascript
基于AngularJS实现iOS8自带的计算器
2016/09/12 Javascript
详解AngularJS验证、过滤器、指令
2017/01/04 Javascript
node.js中实现kindEditor图片上传功能的方法教程
2017/04/26 Javascript
微信小程序媒体组件详解(视频,音乐,图片)
2017/09/19 Javascript
IntelliJ IDEA编辑器配置vue高亮显示
2019/09/26 Javascript
微信小程序中插入激励视频广告并获取收益(实例代码)
2019/12/06 Javascript
使用Python+Splinter自动刷新抢12306火车票
2018/01/03 Python
详解python持久化文件读写
2019/04/06 Python
python 实现Flask中返回图片流给前端展示
2020/01/09 Python
基于Python3.6中的OpenCV实现图片色彩空间的转换
2020/02/03 Python
django Layui界面点击弹出对话框并请求逻辑生成分页的动态表格实例
2020/05/12 Python
Python如何实现机器人聊天
2020/09/10 Python
Python爬虫教程之利用正则表达式匹配网页内容
2020/12/08 Python
英国奢侈品网站:MatchesFashion
2016/12/16 全球购物
Sofft鞋官网:世界知名鞋类品牌
2017/03/28 全球购物
英国街头品牌:Bee Inspired Clothing
2018/02/12 全球购物
保时捷设计:Porsche Design
2019/03/30 全球购物
英国Flybe航空官网:欧洲最大的独立支线廉价航空公司
2019/07/15 全球购物
在C语言中"指针和数组等价"到底是什么意思?
2014/03/24 面试题
酒店司机岗位职责
2013/12/14 职场文书
工作经常出错的检讨书
2014/09/13 职场文书
教师四风自我剖析材料
2014/09/30 职场文书
z-index不起作用
2021/03/31 HTML / CSS
Vue详细的入门笔记
2021/05/10 Vue.js
Mysql实现简易版搜索引擎的示例代码
2021/08/30 MySQL