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 相关文章推荐
打开超链需要“确认”对话框的方法
Mar 08 Javascript
jquery创建表格(自动增加表格)代码分享
Dec 25 Javascript
一个简单的实现下拉框多选的插件可移植性比较好
May 05 Javascript
JavaScript获取function所有参数名的方法
Oct 30 Javascript
JavaScript面试题大全(推荐)
Sep 22 Javascript
浅谈微信页面入口文件被缓存解决方案
Sep 29 Javascript
React Native中Mobx的使用方法详解
Dec 04 Javascript
vue组件中iview的modal组件爬坑问题之modal的显示与否应该是使用v-show
Apr 12 Javascript
taro小程序添加骨架屏的实现代码
Nov 15 Javascript
JavaScript 实现HTML DOM增删改查操作的常见方法详解
Jan 04 Javascript
解决elementui表格操作列自适应列宽
Dec 28 Javascript
JavaScript异步操作中串行和并行
Nov 20 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
了解Joomla 这款来自国外的php网站管理系统
2010/03/11 PHP
CodeIgniter上传图片成功的全部过程分享
2013/08/12 PHP
CodeIgniter模板引擎使用实例
2014/07/15 PHP
php采用curl实现伪造IP来源的方法
2014/11/21 PHP
tp5.1 框架数据库-数据集操作实例分析
2020/05/26 PHP
Jquery CheckBox全选方法代码附js checkbox全选反选代码
2010/06/09 Javascript
动感效果的TAB选项卡jquery 插件
2011/07/09 Javascript
javascript中[]和{}对象使用介绍
2013/03/20 Javascript
SpringBoot+Vue前后端分离,使用SpringSecurity完美处理权限问题的解决方法
2018/01/09 Javascript
原生JS实现弹幕效果的简单操作指南
2020/11/10 Javascript
vue3.0 项目搭建和使用流程
2021/03/04 Vue.js
[51:30]OG vs LGD 2018国际邀请赛淘汰赛BO3 第二场 8.26
2018/08/30 DOTA
python fabric实现远程操作和部署示例
2014/03/25 Python
在Python的Django框架中用流响应生成CSV文件的教程
2015/05/02 Python
使用Python编写基于DHT协议的BT资源爬虫
2016/03/19 Python
Python的Flask框架中配置多个子域名的方法讲解
2016/06/07 Python
PyQt5打开文件对话框QFileDialog实例代码
2018/02/07 Python
python实现跨excel的工作表sheet之间的复制方法
2018/05/03 Python
python+mysql实现学生信息查询系统
2019/02/21 Python
python 弹窗提示警告框MessageBox的实例
2019/06/18 Python
FFrpc python客户端lib使用解析
2019/08/24 Python
Python input函数使用实例解析
2019/11/22 Python
python 如何把docker-compose.yaml导入到数据库相关条目里
2021/01/15 Python
HTML5中Canvas与SVG的画图原理比较
2013/01/16 HTML / CSS
美国最好的保健品打折网店:Swanson
2017/08/04 全球购物
几个常见的消息中间件(MOM)
2014/01/08 面试题
中学实习教师自我鉴定
2013/12/12 职场文书
应届大学生简历中的自我评价
2014/01/15 职场文书
护理专业优质毕业生自荐书
2014/01/31 职场文书
公司管理建议书范文
2014/03/12 职场文书
大学生社会实践自我鉴定
2014/03/24 职场文书
交通安全寄语大全
2014/04/08 职场文书
班级课外活动总结
2014/07/09 职场文书
营销总监岗位职责
2014/09/16 职场文书
jquery插件实现图片悬浮
2021/04/16 jQuery
Golang全局变量加锁的问题解决
2021/05/08 Golang