JavaScript 嵌套函数指向this对象错误的解决方法


Posted in Javascript onMarch 15, 2010

先看一段嵌套了两层function的JavaScript代码:

var me = { 
name : 'Jimbor', 
blog : 'http://jmedia.cn/', 
sayMyName : function(){ 
var pre = 'My name is: '; 
function displayName(){ 
alert(pre + this.name); 
} 
displayName(); 
} 
} 
me.sayMyName();

从代码上看,我们希望通过sayMyName()的调用来显示me的name属性,即:My name is: Jimbor。但浏览器的执行结果是:
My name is:

是什么原因使name属性没有正确显示呢?原来JavaScript对于全局函数内的this绑定为全局对象,而对于嵌套函数也采用了相同的解释。这个错误产生的后果是不能轻易使用嵌套函数来完成某些特殊的任务,因为这些函数对this所指向的对象解释不同。
当然对于这个例子,我们完全可以不用嵌套的函数来完成相应的功能。但是对于某些应用可能会需要这种结构。幸运的是,我们还是有办法来纠正这个错误的。
方法一:用apply()函数
apply(this_obj, params_array)

apply()函数可以在调用某个函数时重写this所指向的对象,它接受两个参数,第一个this_obj即想要重写this所指向的对象,params_array则是用来传递给调用函数的参数数组。我们把原来的代码改写为:
var me = { 
name : 'Jimbor', 
blog : 'http://jmedia.cn/', 
sayMyName : function(){ 
var pre = 'My name is: '; 
function displayName(){ 
alert(pre + this.name); 
} 
displayName.apply(me); 
} 
} 
me.sayMyName();

再看浏览器执行结果:
My name is: Jimbor
类似的函数还有call()。区别是call()传参的方式是一个接一个而不是打包成一个数组。
方法二:用that替换this
即我们可以在最外层的函数定义一个变量来指向this所指向的对象,一旦内部的函数需要调用this时,我们就用这个定义的变量。通常根据习惯,会将这个变量命名为that。那么原来的代码可以改成这样:
var me = { 
name : 'Jimbor', 
blog : 'http://jmedia.cn/', 
sayMyName : function(){ 
var pre = 'My name is: '; 
var that = this; 
function displayName(){ 
alert(pre + that.name); 
} 
displayName(); 
} 
} 
me.sayMyName();

很好用,不是吗?因为不会涉及到具体的对象指定,所以更推荐第二种方法。
Javascript 相关文章推荐
IE中createElement需要注意的一个问题
Jul 13 Javascript
我的javascript 函数链之演变
Apr 07 Javascript
获取客户端网卡MAC地址和IP地址实现JS代码
Mar 17 Javascript
JavaScript弹出新窗口后向父窗口输出内容的方法
Apr 06 Javascript
深入理解JavaScript中的对象
Jun 04 Javascript
在jQuery中处理XML数据的大致方法
Aug 14 Javascript
JS动态日期时间的获取方法
Sep 28 Javascript
jQuery实现点击按钮文字变成input框点击保存变成文字
May 09 Javascript
React组件生命周期详解
Jul 03 Javascript
vue-cli 脚手架基于Nightwatch的端到端测试环境的过程
Sep 30 Javascript
koa-router路由参数和前端路由的结合详解
May 19 Javascript
JavaScript中Object、map、weakmap的区别分析
Dec 15 Javascript
JQuery 常用操作代码
Mar 14 #Javascript
Jquery Ajax学习实例 向页面发出请求,返回XML格式数据
Mar 14 #Javascript
Jquery cookie操作代码
Mar 14 #Javascript
javascript 解决表单仍然提交即使监听处理函数返回false
Mar 14 #Javascript
jQuery第三课 修改元素属性及内容的代码
Mar 14 #Javascript
jQuery 第二课 操作包装集元素代码
Mar 14 #Javascript
jQuery入门第一课 jQuery选择符
Mar 14 #Javascript
You might like
解决dede生成静态页和动态页转换的一些问题,及火车采集入库生成动态的办法
2007/03/29 PHP
php empty函数判断mysql表单是否为空
2010/04/12 PHP
php加密解密实用类分享
2014/01/07 PHP
php实现按文件名搜索文件的远程文件查找器
2014/05/10 PHP
PHP编程中的__clone()方法使用详解
2015/11/27 PHP
Symfony2学习笔记之插件格式分析
2016/03/17 PHP
PHP 常用时间函数资料整理
2016/10/22 PHP
PHP实现二维数组按照指定的字段进行排序算法示例
2019/04/23 PHP
JavaScript是否可实现多线程  深入理解JavaScript定时机制
2009/12/22 Javascript
javascript 模式设计之工厂模式详细说明
2010/05/10 Javascript
javascript中的取反再取反~~没有意义
2014/04/06 Javascript
Jquery中的$.each获取各种返回类型数据的使用方法
2015/05/03 Javascript
PHP结合jQuery实现的评论顶、踩功能
2015/07/22 Javascript
jQuery webuploader分片上传大文件
2016/11/07 Javascript
从理论角度讨论JavaScript闭包
2019/04/03 Javascript
详解JavaScript的变量
2019/04/04 Javascript
javascript面向对象创建对象的方式小结
2019/07/29 Javascript
vue项目中使用AES实现密码加密解密(ECB和CBC两种模式)
2019/08/12 Javascript
python算法学习之桶排序算法实例(分块排序)
2013/12/18 Python
Python利用pyHook实现监听用户鼠标与键盘事件
2014/08/21 Python
想学python 这5本书籍你必看!
2018/12/11 Python
在python中使用xlrd获取合并单元格的方法
2018/12/26 Python
numpy和pandas中数组的合并、拉直和重塑实例
2019/06/28 Python
python使用flask与js进行前后台交互的例子
2019/07/19 Python
Python底层封装实现方法详解
2020/01/22 Python
python中的socket实现ftp客户端和服务器收发文件及md5加密文件
2020/04/01 Python
Python virtualenv虚拟环境实现过程解析
2020/04/18 Python
HTML5添加鼠标悬浮音响效果不使用FLASH
2014/04/23 HTML / CSS
AJAX都有哪些有点和缺点
2012/11/03 面试题
简历自荐信
2013/12/02 职场文书
服务之星获奖感言
2014/01/21 职场文书
求职信的七个关键技巧
2014/02/05 职场文书
语文教学感言
2014/02/06 职场文书
物业管理毕业生的自我评价
2014/02/17 职场文书
国家机关领导干部民主生活会对照检查材料思想汇报
2014/09/17 职场文书
MySQL的表级锁,行级锁,排它锁和共享锁
2022/07/15 MySQL