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 相关文章推荐
Document 对象的常用方法
Jul 31 Javascript
JavaScript 高级篇之函数 (四)
Apr 07 Javascript
jquery获取tr中控件值并操作tr实现思路
Mar 27 Javascript
jquery中的常用事件bind、hover、toggle等示例介绍
Jul 21 Javascript
javascript用函数实现对象的方法
May 14 Javascript
D3.js实现雷达图的方法详解
Sep 22 Javascript
javaScript 事件绑定、事件冒泡、事件捕获和事件执行顺序整理总结
Oct 10 Javascript
Yarn的安装与使用详细介绍
Oct 25 Javascript
Vue.js基础知识小结
Jan 13 Javascript
vue forEach循环数组拿到自己想要的数据方法
Sep 21 Javascript
jQuery-ui插件sortable实现自由拖动排序
Dec 01 jQuery
vue点击页面空白处实现保存功能
Nov 06 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简单检测网址是否能够正常打开的方法
2016/09/04 PHP
Ruffy javascript 学习笔记
2009/11/30 Javascript
javascript 隔行换色函数代码
2010/10/24 Javascript
javascript中substr,substring,slice.splice的区别说明
2010/11/25 Javascript
jquery选择器排除某个DOM元素的方法(实例演示)
2014/04/25 Javascript
js实现图片和链接文字同步切换特效的方法
2015/02/20 Javascript
jquery判断复选框是否选中进行答题提示特效
2015/12/10 Javascript
jQuery插件实现带圆点的焦点图片轮播切换
2016/01/18 Javascript
基于jquery实现表格内容筛选功能实例解析
2016/05/09 Javascript
简单实现轮播图效果的实例
2016/07/15 Javascript
NodeJS设计模式总结【单例模式,适配器模式,装饰模式,观察者模式】
2017/09/06 NodeJs
Angular js 实现添加用户、修改密码、敏感字、下拉菜单的综合操作方法
2017/10/24 Javascript
实例详解BootStrap的动态模态框及静态模态框
2018/08/13 Javascript
Vue项目中ESlint规范示例代码
2019/07/04 Javascript
详解Vue 数据更新了但页面没有更新的 7 种情况汇总及延伸总结
2020/05/28 Javascript
Vue-cli3生成的Vue项目加载Mxgraph方法示例
2020/05/31 Javascript
JS事件循环机制event loop宏任务微任务原理解析
2020/08/04 Javascript
vue实现日历表格(element-ui)
2020/09/24 Javascript
[00:14]PWL:老朋友Mushi拍VLOG与中国玩家问好
2020/11/04 DOTA
Python编码时应该注意的几个情况
2013/03/04 Python
linux系统使用python获取内存使用信息脚本分享
2014/01/15 Python
粗略分析Python中的内存泄漏
2015/04/23 Python
Python多线程爬虫简单示例
2016/03/04 Python
python、java等哪一门编程语言适合人工智能?
2017/11/13 Python
Python基于pandas实现json格式转换成dataframe的方法
2018/06/22 Python
Python使用pyautogui模块实现自动化鼠标和键盘操作示例
2018/09/04 Python
500行Python代码打造刷脸考勤系统
2019/06/03 Python
解决pyecharts在jupyter notebook中使用报错问题
2020/04/23 Python
numpy库ndarray多维数组的维度变换方法(reshape、resize、swapaxes、flatten)
2020/04/28 Python
Keras自动下载的数据集/模型存放位置介绍
2020/06/19 Python
AT&T Wireless:手机、无限数据计划和配件
2018/06/03 全球购物
3个CCIE对一个工程师的面试题
2012/05/06 面试题
什么是设计模式
2012/06/17 面试题
销售经理工作职责
2014/02/03 职场文书
教书育人演讲稿
2014/09/11 职场文书
2016年第32个教师节致辞
2015/11/26 职场文书