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 放大镜 v1.0 基于Yui2 实现的放大镜效果
Mar 08 Javascript
JS代码放在head和body中的区别分析
Dec 01 Javascript
JQuery实现表格中相同单元格合并示例代码
Jun 26 Javascript
js全选实现和判断是否有复选框选中的方法
Feb 17 Javascript
javascript数组去重的方法汇总
Apr 14 Javascript
JavaScript必知必会(七)js对象继承
Jun 08 Javascript
微信小程序 HTTPS报错整理常见问题及解决方案
Dec 14 Javascript
微信小程序 登录实例详解
Jan 16 Javascript
Vue.js常用指令之循环使用v-for指令教程
Jun 27 Javascript
Angular4学习笔记router的简单使用
Mar 30 Javascript
如何以Angular的姿势打开Font-Awesome详解
Apr 22 Javascript
vue实现登陆页面开发实践
May 30 Vue.js
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学习之字符串比较和查找
2011/04/17 PHP
PHP之生成GIF动画的实现方法
2013/06/07 PHP
PHP扩展Memcache分布式部署方案
2015/12/06 PHP
Swoole 5将移除自动添加Event::wait()特性详解
2019/07/10 PHP
PHP使用gearman进行异步的邮件或短信发送操作详解
2020/02/27 PHP
HTML5如何适配 iPhone IOS 底部黑条
2021/03/09 HTML / CSS
JavaScript 计算图片加载数量的代码
2011/01/01 Javascript
js制作的鼠标悬浮时产生的下拉框效果
2012/10/27 Javascript
JS 退出系统并跳转到登录界面的实现代码
2013/06/29 Javascript
jquery对ajax的支持介绍
2013/12/10 Javascript
js 判断浏览器使用的语言示例代码
2014/03/22 Javascript
js实现Select头像选择实时预览代码
2015/08/17 Javascript
分享两款带遮罩的jQuery弹出框
2015/12/30 Javascript
深入理解React中es6创建组件this的方法
2016/08/29 Javascript
利用Angularjs中模块ui-route管理状态的方法
2016/12/27 Javascript
jquery一键控制checkbox全选、反选或全不选
2017/10/16 jQuery
node.js使用免费的阿里云ip查询获取ip所在地【推荐】
2018/09/03 Javascript
JQuery获取可视区尺寸和文档尺寸及制作悬浮菜单示例
2019/05/14 jQuery
生产制造追溯系统之再说条码打印
2019/06/03 Javascript
这样回答继承可能面试官更满意
2019/12/10 Javascript
[06:25]DOTA2英雄梦之声_第17期_大地之灵
2014/06/20 DOTA
Python 中的 else详解
2016/04/23 Python
Python获取本机所有网卡ip,掩码和广播地址实例代码
2018/01/22 Python
selenium+python自动化测试之多窗口切换
2019/01/23 Python
Django认证系统实现的web页面实现代码
2019/08/12 Python
Python使用sqlite3模块内置数据库
2020/05/07 Python
Python的collections模块真的很好用
2021/03/01 Python
香港唯港荟酒店预订:Hotel ICON
2018/03/27 全球购物
冰淇淋开店创业计划书
2014/02/01 职场文书
2014年商场超市庆元旦活动方案
2014/02/14 职场文书
小学生我的梦想演讲稿
2014/08/21 职场文书
行政前台岗位职责
2015/04/16 职场文书
紧急通知
2015/04/17 职场文书
学籍证明模板
2015/06/18 职场文书
详解Python+OpenCV进行基础的图像操作
2022/02/15 Python
Tomcat 与 maven 的安装与使用教程
2022/06/16 Servers