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 相关文章推荐
求解开jscript.encode代码的asp函数
Feb 28 Javascript
javascript Prototype 对象扩展
May 15 Javascript
一个XML格式数据转换为图表的例子
Feb 09 Javascript
基于jquery库的tab新形式使用
Nov 16 Javascript
javascript克隆对象深度介绍
Nov 20 Javascript
Javascript页面跳转常见实现方式汇总
Nov 28 Javascript
JavaScript制作简易计算器(不用eval)
Feb 05 Javascript
完美解决浏览器跨域的几种方法(汇总)
May 08 Javascript
vue2.0 兄弟组件(平级)通讯的实现代码
Jan 15 Javascript
详解在Javascript中进行面向切面编程
Apr 28 Javascript
解决vue项目刷新后,导航菜单高亮显示的位置不对问题
Nov 01 Javascript
vue+openlayers绘制省市边界线
Dec 24 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
PHP MSSQL 存储过程的方法
2008/12/24 PHP
ThinkPHP分页实例
2014/10/15 PHP
PHP两种实现无级递归分类的方法
2017/03/02 PHP
php+resumablejs实现的分块上传 断点续传功能示例
2017/04/18 PHP
PHP实现的ID混淆算法类与用法示例
2018/08/10 PHP
php根据命令行参数生成配置文件详解
2019/03/15 PHP
javaScript同意等待代码实现心得
2011/01/01 Javascript
使用Post提交时须将空格转换成加号的解释
2013/01/14 Javascript
JQUERY实现左侧TIPS滑进滑出效果示例
2013/06/27 Javascript
javascript进行四舍五入方法汇总
2014/12/16 Javascript
webapp框架AngularUI的demo改造之路
2014/12/21 Javascript
js动态生成Html元素实现Post操作(createElement)
2015/09/14 Javascript
jQuery仿写百度百科的目录树
2017/01/03 Javascript
详解webpack 入门总结和实践(按需异步加载,css单独打包,生成多个入口文件)
2017/06/20 Javascript
Three.js实现绘制字体模型示例代码
2017/09/26 Javascript
基于vue,vue-router, vuex及addRoutes进行权限控制问题
2018/05/02 Javascript
Javascript 类型转换、封闭函数及常见内置对象操作示例
2019/11/15 Javascript
JS document文档的简单操作完整示例
2020/01/13 Javascript
mustache.js实现首页元件动态渲染的示例代码
2020/12/28 Javascript
在Gnumeric下使用Python脚本操作表格的教程
2015/04/14 Python
python创建关联数组(字典)的方法
2015/05/04 Python
python的文件操作方法汇总
2017/11/10 Python
详解python string类型 bytes类型 bytearray类型
2017/12/16 Python
通过Python模块filecmp 对文件比较的实现方法
2018/06/29 Python
Django实现一对多表模型的跨表查询方法
2018/12/18 Python
Python3开发环境搭建详细教程
2020/06/18 Python
python利用opencv保存、播放视频
2020/11/02 Python
在Ubuntu中安装并配置Pycharm教程的实现方法
2021/01/06 Python
巴黎一票通:The Paris Pass
2018/02/10 全球购物
幼儿园春季开学寄语
2014/04/03 职场文书
致共产党员倡议书
2014/04/16 职场文书
安全目标责任书
2014/07/22 职场文书
2016年10月份红领巾广播稿
2015/12/21 职场文书
六一儿童节致辞稿(3篇)
2019/07/11 职场文书
浅谈怎么给Python添加类型标注
2021/06/08 Python
java版 简单三子棋游戏
2022/05/04 Java/Android