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 写类方式之三
Jul 05 Javascript
JavaScript 10件让人费解的事情
Feb 15 Javascript
监控 url fragment变化的js代码
Apr 19 Javascript
javascript的列表切换【实现代码】
May 03 Javascript
jquery树形菜单效果的简单实例
Jun 06 Javascript
微信小程序 地图(map)实例详解
Nov 16 Javascript
JavaScript简单验证表单空值及邮箱格式的方法
Jan 20 Javascript
vue.js $refs和$emit 父子组件交互的方法
Dec 20 Javascript
在微信小程序中保存网络图片
Feb 12 Javascript
Vue对象赋值视图不更新问题及解决方法
Jun 03 Javascript
VSCode 添加自定义注释的方法(附带红色警戒经典注释风格)
Aug 27 Javascript
基于原生JS封装的Modal对话框插件的示例代码
Sep 09 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
mysql5写入和读出乱码解决
2006/11/25 PHP
php实现网页缓存的工具类分享
2015/07/14 PHP
thinkphp5.1框架中容器(Container)和门面(Facade)的实现方法分析
2019/08/05 PHP
Laravel 手动开关 Eloquent 修改器的操作方法
2019/12/30 PHP
PHP中关于php.ini参数优化详解
2020/02/28 PHP
JavaScript 函数式编程的原理
2009/10/16 Javascript
JQuery获取与设置HTML元素的内容或文本的实现代码
2014/06/20 Javascript
IE浏览器不支持getElementsByClassName的解决方法
2014/08/27 Javascript
jQuery仿360导航页图标拖动排序效果代码分享
2015/08/24 Javascript
分享jQuery插件的学习笔记
2016/01/14 Javascript
JS中取二维数组中最大值的方法汇总
2016/04/17 Javascript
js阻止浏览器默认行为触发的通用方法(推荐)
2016/05/15 Javascript
js实现hashtable的赋值、取值、遍历操作实例详解
2016/12/25 Javascript
详解Node.js access_token的获取、存储及更新
2017/06/20 Javascript
NodeJs实现定时任务的示例代码
2017/12/05 NodeJs
Vue+ElementUI 中级联选择器Bug问题的解决
2020/07/31 Javascript
Bootstrap FileInput实现图片上传功能
2021/01/28 Javascript
[43:33]EG vs Spirit Supermajor 败者组 BO3 第一场 6.4
2018/06/05 DOTA
python实现用户登陆邮件通知的方法
2015/07/09 Python
Python运维之获取系统CPU信息的实现方法
2018/06/11 Python
python微信公众号之关注公众号自动回复
2018/10/25 Python
在Pycharm中使用GitHub的方法步骤
2019/06/13 Python
详解numpy.meshgrid()方法使用
2019/08/01 Python
python3爬取torrent种子链接实例
2020/01/16 Python
python读取csv文件指定行的2种方法详解
2020/02/13 Python
实现ECharts双Y轴左右刻度线一致的例子
2020/05/16 Python
浅谈PyTorch中in-place operation的含义
2020/06/27 Python
python3 通过 pybind11 使用Eigen加速代码的步骤详解
2020/12/07 Python
台湾森森购物网:U-mall
2017/10/16 全球购物
俄罗斯购买自行车网站:Vamvelosiped
2021/01/29 全球购物
解决python 输出到csv 出现多空行的情况
2021/03/24 Python
基层党组织公开承诺书
2014/03/28 职场文书
爱国演讲稿400字
2014/05/07 职场文书
模具设计与制造专业求职信
2014/07/19 职场文书
2015年度党员自我评价范文
2015/03/03 职场文书
演讲稿:​快乐,从不抱怨开始!
2019/04/02 职场文书