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 相关文章推荐
转一个日期输入控件,支持FF
Apr 27 Javascript
有关js的变量作用域和this指针的讨论
Dec 16 Javascript
Firefox/Chrome/Safari的中可直接使用$/$$函数进行调试
Feb 13 Javascript
js 图片随机不定向浮动的实现代码
Jul 02 Javascript
Jquery:ajax实现翻页无刷新功能代码
Aug 05 Javascript
JavaScript中document对象使用详解
Jan 06 Javascript
JS文字球状放大效果代码分享
Aug 19 Javascript
使用vue.js2.0 + ElementUI开发后台管理系统详细教程(二)
Jan 21 Javascript
微信小程序 下拉菜单简单实例
Apr 13 Javascript
JS使用正则表达式验证身份证号码
Jun 23 Javascript
JavaScript判断浏览器和hack滚动条的写法
Jul 23 Javascript
vue路由嵌套的SPA实现步骤
Nov 06 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
Laravel 登录后清空COOKIE的操作方法
2019/10/14 PHP
PHP7创建销毁session的实例方法
2020/02/03 PHP
tp5框架前台无限极导航菜单类实现方法分析
2020/03/29 PHP
一些有关检查数据的JS代码
2006/09/07 Javascript
javascript中的prototype属性使用说明(函数功能扩展)
2010/08/16 Javascript
动态显示可输入的字数提示还可以输入的字数
2014/04/01 Javascript
javascript的事件触发器介绍的实现
2014/06/05 Javascript
前端js实现文件的断点续传 后端PHP文件接收
2016/10/14 Javascript
浅谈jQuery的bind和unbind事件(绑定和解绑事件)
2017/03/02 Javascript
用vue和node写的简易购物车实现
2017/04/25 Javascript
VueJS组件之间通过props交互及验证的方式
2017/09/04 Javascript
Vue集成Iframe页面的方法示例
2017/12/12 Javascript
vue使用element-ui的el-input监听不了回车事件的解决方法
2018/01/12 Javascript
vue远程加载sfc组件思路详解
2019/12/25 Javascript
实例讲解React 组件生命周期
2020/07/08 Javascript
详解vite+ts快速搭建vue3项目以及介绍相关特性
2021/02/25 Vue.js
[01:32:10]NAVI vs VG Supermajor 败者组 BO3 第一场 6.5
2018/06/06 DOTA
[01:06:43]完美世界DOTA2联赛PWL S3 PXG vs GXR 第二场 12.19
2020/12/24 DOTA
Python中的并发编程实例
2014/07/07 Python
python中循环语句while用法实例
2015/05/16 Python
python+VTK环境搭建及第一个简单程序代码
2017/12/13 Python
Python理解递归的方法总结
2019/01/28 Python
Python实现的序列化和反序列化二叉树算法示例
2019/03/02 Python
Python自定义一个异常类的方法
2019/06/27 Python
Django 权限认证(根据不同的用户,设置不同的显示和访问权限)
2019/07/24 Python
浅析使用Python搭建http服务器
2019/10/27 Python
python GUI库图形界面开发之PyQt5不规则窗口实现与显示GIF动画的详细方法与实例
2020/03/09 Python
Python devel安装失败问题解决方案
2020/06/09 Python
举例讲解Python装饰器
2020/12/24 Python
Html5游戏开发之乒乓Ping Pong游戏示例(二)
2013/01/21 HTML / CSS
Book Depository美国:全球领先的专业网上书店之一
2019/08/14 全球购物
个人自我评价分享
2013/12/20 职场文书
大学生职业生涯规划方案
2014/01/03 职场文书
四风问题查摆材料
2014/08/25 职场文书
无财产离婚协议书范本
2014/10/28 职场文书
《吃水不忘挖井人》教学反思
2016/02/22 职场文书