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 相关文章推荐
javascript document.images实例
May 27 Javascript
FLASH 广告之外的链接
Dec 16 Javascript
jquery中添加属性和删除属性
Jun 03 Javascript
使用JS中的exec()方法构造正则表达式验证
Aug 01 Javascript
jquery实现图片平滑滚动详解
Mar 22 jQuery
React Native 环境搭建的教程
Aug 19 Javascript
解决angularjs中同步执行http请求的方法
Aug 13 Javascript
移动端图片上传旋转、压缩问题的方法
Oct 16 Javascript
详解javascript对数组和json数组的操作
Apr 15 Javascript
微信小程序传值以及获取值方法的详解
Apr 29 Javascript
vuex存储复杂参数(如对象数组等)刷新数据丢失的解决方法
Nov 05 Javascript
js实现ajax的用户简单登入功能
Jun 18 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加密扩展库Mcrypt安装和实例
2013/11/10 PHP
php使用filter过滤器验证邮箱 ipv6地址 url验证
2013/12/25 PHP
php获取URL中带#号等特殊符号参数的解决方法
2014/09/02 PHP
实现PHP+Mysql无限分类的方法汇总
2015/03/02 PHP
php里array_work用法实例分析
2015/07/13 PHP
PHP防止sql注入小技巧之sql预处理原理与实现方法分析
2019/12/13 PHP
[对联广告] JS脚本类
2006/08/27 Javascript
Javascript 去除数组的重复元素
2010/05/04 Javascript
扩展easyui.datagrid,添加数据loading遮罩效果代码
2010/11/02 Javascript
浅析Js(Jquery)中,字符串与JSON格式互相转换的示例(直接运行实例)
2013/07/09 Javascript
JS 如何获取radio选中后的值及不选择取radio的值
2013/10/28 Javascript
javaScript实现浮点数转十六进制字符
2013/10/29 Javascript
javascript计算当月剩余天数(天数计算器)示例代码
2014/01/09 Javascript
对JavaScript中this指针的新理解分享
2015/01/31 Javascript
js图片上传前预览功能(兼容所有浏览器)
2016/08/24 Javascript
微信小程序 地图map实例详解
2017/06/07 Javascript
vue对storejs获取的数据进行处理时遇到的几种问题小结
2018/03/20 Javascript
nodejs实现获取本地文件夹下图片信息功能示例
2019/06/22 NodeJs
layui动态绑定事件的方法
2019/09/20 Javascript
浅析vue中的nextTick
2020/12/28 Vue.js
Python 学习笔记
2008/12/27 Python
python和shell实现的校验IP地址合法性脚本分享
2014/10/23 Python
通过C++学习Python
2015/01/20 Python
Python正则表达式常用函数总结
2017/06/24 Python
python如何生成网页验证码
2018/07/28 Python
Python爬虫库BeautifulSoup获取对象(标签)名,属性,内容,注释
2020/01/25 Python
快速了解Python开发环境Spyder
2020/06/29 Python
如何使用python自带IDLE的几种方法
2020/10/10 Python
审计工作个人的自我评价
2013/12/25 职场文书
美国探亲签证邀请信
2014/02/05 职场文书
幼儿园三八妇女节活动方案
2014/03/11 职场文书
致共产党员倡议书
2014/04/16 职场文书
简单租房协议书范本
2014/08/20 职场文书
财务会计个人原因辞职信
2019/06/21 职场文书
利用前端HTML+CSS+JS开发简单的TODOLIST功能(记事本)
2021/04/13 Javascript
pytorch中[..., 0]的用法说明
2021/05/20 Python