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和FireFox的脚本
May 18 Javascript
javascript中定义类的方法汇总
Dec 28 Javascript
Jquery中CSS选择器用法分析
Feb 10 Javascript
javascript函数特点实例分析
May 14 Javascript
JavaScript简单实现鼠标移动切换图片的方法
Feb 23 Javascript
Web开发必知Javascript技巧大全
Feb 23 Javascript
Angularjs CURD 详解及实例代码
Sep 14 Javascript
jQuery实现倒计时(倒计时年月日可自己输入)
Dec 02 Javascript
详解angularJs中自定义directive的数据交互
Jan 13 Javascript
微信小程序图表插件(wx-charts)实例代码
Jan 17 Javascript
js中this的指向问题归纳总结
Nov 28 Javascript
Vue+Element UI 树形控件整合下拉功能菜单(tree + dropdown +input)
Aug 28 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
用PHP和ACCESS写聊天室(五)
2006/10/09 PHP
php变量作用域的深入解析
2013/06/03 PHP
PHP常用函数和常见疑难问题解答
2014/03/05 PHP
PHP实现货币换算的方法
2014/11/29 PHP
php隐藏实际地址的文件下载方法
2015/04/18 PHP
php使用json_decode后数字对象转换成了科学计数法的解决方法
2017/02/20 PHP
javascript 得到变量类型的函数
2010/05/19 Javascript
Extjs4 GridPanel的主要配置参数详细介绍
2013/04/18 Javascript
jquery实现的一个简单进度条效果实例
2014/05/12 Javascript
当前流行的JavaScript代码风格指南
2014/09/10 Javascript
JS如何实现文本框随文本的长度而增长
2015/07/30 Javascript
让浏览器崩溃的12行JS代码(DoS攻击分析及防御)
2016/10/10 Javascript
又一款MVVM组件 构建自己的Vue组件(2)
2017/03/13 Javascript
JavaScript中双向数据绑定详解
2017/05/03 Javascript
微信小程序上传图片功能(附后端代码)
2020/06/19 Javascript
解决select2在bootstrap modal中不能正常使用的问题
2018/08/09 Javascript
原生JS实现的跳一跳小游戏完整实例
2019/01/27 Javascript
解决JQuery的ajax函数执行失败alert函数弹框一闪而过问题
2019/04/10 jQuery
express框架中使用jwt实现验证的方法
2019/08/25 Javascript
基于Web Audio API实现音频可视化效果
2020/06/12 Javascript
[01:02:05]LGD vs Mineski 2018国际邀请赛小组赛BO2 第一场 8.19
2018/08/21 DOTA
python 参数列表中的self 显式不等于冗余
2008/12/01 Python
python解析xml文件操作实例
2014/10/05 Python
简介Python设计模式中的代理模式与模板方法模式编程
2016/02/02 Python
Python利用operator模块实现对象的多级排序详解
2017/05/09 Python
Python3显示当前时间、计算时间差及时间加减法示例代码
2019/09/07 Python
Python WebSocket长连接心跳与短连接的示例
2020/11/24 Python
python 实现Requests发送带cookies的请求
2021/02/08 Python
The Athlete’s Foot新西兰:新西兰最大的运动鞋零售商
2019/12/23 全球购物
会议接待欢迎词
2014/01/12 职场文书
招商引资工作汇报
2014/10/28 职场文书
先进个人评语大全
2015/01/04 职场文书
环卫工人慰问信
2015/02/15 职场文书
六一文艺汇演主持词
2015/06/30 职场文书
2016年校园重阳节广播稿
2015/12/18 职场文书
Element-ui Layout布局(Row和Col组件)的实现
2021/12/06 Vue.js