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 相关文章推荐
js TextArea的选中区域处理
Dec 28 Javascript
解决Extjs上传图片无法预览的解决方法
Mar 22 Javascript
jQuery操作表格(table)的常用方法、技巧汇总
Apr 12 Javascript
moment.js轻松实现获取当前日期是当年的第几周
Feb 05 Javascript
jquery使整个div区域可以点击的方法
Jun 24 Javascript
两款JS脚本判断手机浏览器类型跳转WAP手机网站
Oct 16 Javascript
基于JQuery实现图片轮播效果(焦点图)
Feb 02 Javascript
基于jQuery实现页面搜索功能
Mar 26 Javascript
浅谈Vue父子组件和非父子组件传值问题
Aug 22 Javascript
微信小程序image图片加载完成监听
Aug 31 Javascript
vuecli项目构建SSR服务端渲染的实现
Oct 30 Javascript
element多个表单校验的实现
May 27 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模板页面中分页代码的解析
2009/02/06 PHP
ThinkPHP中RBAC类的四种用法分析
2014/11/24 PHP
yii,CI,yaf框架+smarty模板使用方法
2015/12/29 PHP
php getcwd与dirname(__FILE__)区别详解
2016/09/24 PHP
PHP实现的字符串匹配算法示例【sunday算法】
2017/12/19 PHP
实例讲解通过​PHP创建数据库
2019/01/20 PHP
laravel-admin select框默认选中的方法
2019/10/03 PHP
JavaScript与DropDownList 区别分析
2010/01/01 Javascript
20个非常棒的Jquery实用工具 国外文章
2010/01/01 Javascript
JS Range HTML文档/文字内容选中、库及应用介绍
2011/05/12 Javascript
原生js操作checkbox用document.getElementById实现
2013/10/12 Javascript
js实现键盘控制DIV移动的方法
2015/01/10 Javascript
jQuery中innerWidth()方法用法实例
2015/01/19 Javascript
jQuery.extend 函数及用法详细
2015/09/06 Javascript
Nodejs中session的简单使用及通过session实现身份验证的方法
2016/02/04 NodeJs
浅谈Vue.js路由管理器 Vue Router
2018/08/16 Javascript
JavaScript实现的九种排序算法
2019/03/04 Javascript
JS 设计模式之:单例模式定义与实现方法浅析
2020/05/06 Javascript
[51:44]2018DOTA2亚洲邀请赛 4.3 突围赛 Optic vs iG 第二场
2018/04/04 DOTA
在Python中使用SimpleParse模块进行解析的教程
2015/04/11 Python
Python tkinter实现的图片移动碰撞动画效果【附源码下载】
2018/01/04 Python
基于Python实现迪杰斯特拉和弗洛伊德算法
2020/05/27 Python
深入浅析Python 中 is 语法带来的误解
2019/05/07 Python
Python获取命令实时输出-原样彩色输出并返回输出结果的示例
2019/07/11 Python
Python 解码Base64 得到码流格式文本实例
2020/01/09 Python
CSS3的文字阴影—text-shadow的使用方法
2012/12/25 HTML / CSS
详解CSS3 rem(设置字体大小) 教程
2017/11/21 HTML / CSS
巴西Bo.Bô官方在线商店:经营奢侈品时尚业务
2020/03/16 全球购物
内衣营销方案
2014/03/15 职场文书
运动员获奖感言
2014/08/15 职场文书
大学生推广普通话演讲稿
2014/09/21 职场文书
钓鱼岛事件感想
2015/08/11 职场文书
公司周年庆寄语
2019/06/21 职场文书
古诗文之爱国名句(77句)
2019/09/24 职场文书
Nginx Rewrite使用场景及配置方法解析
2021/04/01 Servers
如何给HttpServletRequest增加消息头
2021/06/30 Java/Android