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 相关文章推荐
一个很简单的办法实现TD的加亮效果.
Jun 29 Javascript
Jquery实现点击切换图片并隐藏显示内容(2种方法实现)
Apr 11 Javascript
js 程序执行与顺序实现详解
May 13 Javascript
jQuery源码解读之addClass()方法分析
Feb 20 Javascript
JQuery日期插件datepicker的使用方法
Mar 03 Javascript
js中setTimeout的妙用--防止循环超时
Mar 06 Javascript
JavaScript实现重力下落与弹性效果的方法分析
Dec 20 Javascript
Vue+Flask实现简单的登录验证跳转的示例代码
Jan 13 Javascript
webpack公共组件引用路径简化小技巧
Jun 15 Javascript
jQuery实现为动态添加的元素绑定事件实例分析
Sep 07 jQuery
JS实现li标签的删除
Apr 12 Javascript
微信小程序图片加载失败时替换为默认图片的方法
Dec 09 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遍历目录与文件夹的多种方法详解
2013/11/14 PHP
PHP编写简单的App接口
2016/08/28 PHP
Yii2框架数据库简单的增删改查语法小结
2016/08/31 PHP
JavaScript网页制作特殊效果用随机数
2007/05/22 Javascript
jQuery弹出层始终垂直居中相对于屏幕或当前窗口
2013/04/01 Javascript
纯JS实现五子棋游戏兼容各浏览器(附源码)
2013/04/24 Javascript
js动态创建标签示例代码
2014/06/09 Javascript
下拉框select的绑定示例
2014/09/04 Javascript
jquery插件unobtrusive实现片段式加载
2015/06/15 Javascript
AngularJS学习笔记之依赖注入详解
2016/05/16 Javascript
JS原型对象的创建方法详解
2016/06/16 Javascript
JS前向后瞻正则表达式定义与用法示例
2016/12/27 Javascript
addeventlistener监听scroll跟touch(实例讲解)
2017/08/04 Javascript
React.Js添加与删除onScroll事件的方法详解
2017/11/03 Javascript
JavaScript实现多态和继承的封装操作示例
2018/08/20 Javascript
vue 修改 data 数据问题并实时显示的方法
2018/08/27 Javascript
详解Vue2 添加对scss的支持
2019/01/02 Javascript
vue模块拖拽实现示例代码
2019/03/09 Javascript
jquery实现掷骰子小游戏
2019/10/24 jQuery
vue-cli+webpack项目打包到服务器后,ttf字体找不到的解决操作
2020/08/28 Javascript
python实现sublime3的less编译插件示例
2014/04/27 Python
将Python中的数据存储到系统本地的简单方法
2015/04/11 Python
pandas数据清洗,排序,索引设置,数据选取方法
2018/05/18 Python
python实现将一个数组逆序输出的方法
2018/06/25 Python
pytorch 常用线性函数详解
2020/01/15 Python
Python读写操作csv和excle文件代码实例
2020/03/16 Python
Python decimal模块使用方法详解
2020/06/08 Python
html5使用Canvas绘图的使用方法
2017/11/21 HTML / CSS
Theory美国官网:后现代都市风时装品牌
2018/05/09 全球购物
澳大利亚排名第一的露营和户外设备在线零售商:Outbax
2020/05/06 全球购物
一道写SQL的面试题和答案
2013/11/19 面试题
法学专业本科生自荐信范文
2013/12/17 职场文书
2014婚礼司仪主持词
2014/03/14 职场文书
GMP办公室主任岗位职责
2014/03/14 职场文书
2014年幼儿园德育工作总结
2014/12/17 职场文书
祝福语集锦:送给毕业同学祝福语
2019/11/21 职场文书