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实现字体选色板实例代码
Nov 20 Javascript
利用了jquery的ajax实现二级联互动菜单
Dec 02 Javascript
直接拿来用的15个jQuery代码片段
Sep 23 Javascript
javascript运算符——逻辑运算符全面解析
Jun 27 Javascript
简单理解vue中Props属性
Oct 27 Javascript
Jquery uploadify 多余的Get请求(404错误)的解决方法
Jan 26 Javascript
详解vue父子组件间传值(props)
Jun 29 Javascript
浅谈vue单一组件下动态修改数据时的全部重渲染
Mar 01 Javascript
在layui框架中select下拉框监听更改事件的例子
Sep 20 Javascript
Vue实现一种简单的无限循环滚动动画的示例
Jan 10 Vue.js
如何用Node.js编写内存效率高的应用程序
Apr 30 Javascript
vue如何在data中引入图片的正确路径
Jun 05 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
注意:php5.4删除了session_unregister函数
2013/08/05 PHP
Zend Framework 2.0事件管理器(The EventManager)入门教程
2014/08/11 PHP
php计算年龄精准到年月日
2015/11/17 PHP
PHP钩子与简单分发方式实例分析
2017/09/04 PHP
一次因composer错误使用引发的问题与解决
2019/03/06 PHP
为Plesk PHP7启用Oracle OCI8扩展方法总结
2019/03/29 PHP
PHP的图像处理实例小结【文字水印、图片水印、压缩图像等】
2019/12/20 PHP
Json2Template.js 基于jquery的插件 绑定JavaScript对象到Html模板中
2011/10/29 Javascript
javascript:void(0)使用探讨
2013/08/27 Javascript
js借助ActiveXObject实现创建文件
2013/09/29 Javascript
js substring从右边获取指定长度字符串(示例代码)
2013/12/23 Javascript
jQuery 滑动方法slideDown向下滑动元素
2014/01/16 Javascript
从零学习node.js之简易的网络爬虫(四)
2017/02/22 Javascript
canvas绘图不清晰的解决方案
2017/02/28 Javascript
浅谈Angular4中常用管道
2017/09/27 Javascript
requireJS模块化实现返回顶部功能的方法详解
2017/10/16 Javascript
vue生命周期实例小结
2018/08/15 Javascript
ES6 Object属性新的写法实例小结
2019/06/25 Javascript
Vue实现图片轮播组件思路及实例解析
2020/05/11 Javascript
Django rest framework实现分页的示例
2018/05/24 Python
Python爬取qq空间说说的实例代码
2018/08/17 Python
分享一个pycharm专业版安装的永久使用方法
2019/09/24 Python
使用Python打造一款间谍程序的流程分析
2020/02/21 Python
纯CSS打造(无图像无js)的非常流行的讲话(语音)气泡效果
2012/12/28 HTML / CSS
英国时尚家具、家居饰品及礼品商店:Graham & Green
2016/09/15 全球购物
介绍一下linux的文件系统
2012/03/20 面试题
销售实习自我鉴定
2013/12/07 职场文书
老师自我鉴定范文
2013/12/25 职场文书
清洁工表扬信
2014/01/08 职场文书
公司新年寄语
2014/04/04 职场文书
《谁的本领大》教后反思
2014/04/25 职场文书
小学生环保倡议书
2014/05/15 职场文书
公司运动会策划方案
2014/05/25 职场文书
生活小常识广播稿
2014/09/16 职场文书
股权转让协议范本
2014/12/07 职场文书
思想品德评语大全
2014/12/31 职场文书