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 相关文章推荐
Add Formatted Text to a Word Document
Jun 15 Javascript
javascript 单例/单体模式(Singleton)
Apr 07 Javascript
js获取浏览器的可视区域尺寸的实现代码
Nov 30 Javascript
JS文本框不能输入空格验证方法
Mar 19 Javascript
js中apply方法的使用详细解析
Nov 04 Javascript
javascript数组快速打乱重排的方法
Jan 02 Javascript
原生JS实现图片翻书效果
Feb 16 Javascript
微信小程序 引入es6 promise
Apr 12 Javascript
微信小程序使用progress组件实现显示进度功能【附源码下载】
Dec 12 Javascript
Vue infinite update loop的问题解决
Apr 23 Javascript
react实现antd线上主题动态切换功能
Aug 12 Javascript
vue之a-table中实现清空选中的数据
Nov 07 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 设置MySQL连接字符集的方法
2011/01/02 PHP
PHP程序员简单的开展服务治理架构操作详解(三)
2020/05/14 PHP
Highslide.js是一款基于js实现的网页中图片展示插件
2020/03/30 Javascript
收集的一些Array及String原型对象的扩展实现代码
2010/12/05 Javascript
JS实现悬浮移动窗口(悬浮广告)的特效
2013/03/12 Javascript
Javascript实现真实字符串剩余字数提示的实例代码
2013/10/22 Javascript
JavaScript中的连字符详解
2013/11/28 Javascript
js登录弹出层特效
2014/03/07 Javascript
JavaScript制作的可折叠弹出式菜单示例
2014/04/04 Javascript
取得元素的左和上偏移量的方法
2014/09/17 Javascript
jQuery的deferred对象详解
2014/11/12 Javascript
jquery validate和jquery form 插件组合实现验证表单后AJAX提交
2015/08/26 Javascript
jquery.qtip提示信息插件用法简单实例
2016/06/17 Javascript
JavaScript探测CSS动画是否已经完成的方法
2016/08/30 Javascript
JS自定义函数对web前端上传的文件进行类型大小判断
2016/10/19 Javascript
JavaScript类的继承方法小结【组合继承分析】
2018/07/11 Javascript
vue插件实现v-model功能
2018/09/10 Javascript
js使用Promise实现简单的Ajax缓存
2018/11/14 Javascript
jQuery 同时获取多个标签的指定内容并储存为数组
2018/11/20 jQuery
Vue-axios-post数据后端接不到问题解决
2020/01/09 Javascript
JS中FormData类实现文件上传
2020/03/27 Javascript
django 连接数据库 sqlite的例子
2019/08/14 Python
Python切图九宫格的实现方法
2019/10/10 Python
解决python3插入mysql时内容带有引号的问题
2020/03/02 Python
FLOS美国官网:意大利高级照明工艺的传奇
2018/08/07 全球购物
美国渔具店:FishUSA
2019/08/07 全球购物
工商管理专业应届生求职信
2013/11/04 职场文书
生产车间班组长岗位职责
2014/01/06 职场文书
活动策划求职信模板
2014/04/21 职场文书
派出所正风肃纪剖析材料
2014/10/10 职场文书
离婚上诉状范文
2015/05/23 职场文书
2015个人年度工作总结范文
2015/05/28 职场文书
爸爸的三轮车观后感
2015/06/16 职场文书
干货分享:推荐信写作技巧!
2019/06/21 职场文书
Nginx配置之实现多台服务器负载均衡
2021/08/02 Servers
Spark SQL 2.4.8 操作 Dataframe的两种方式
2021/10/16 SQL Server