JavaScript中this的使用详解


Posted in Javascript onNovember 08, 2013

我们要记住一句话:this永远指向函数运行时所在的对象!而不是函数被创建时所在的对象。切记…
本文将分三种情况来分析this对象到底身处何方。
普通函数中的this
无论this身处何处,第一要务就是要找到函数运行时的位置。

1 var name="全局";
2 function getName(){
3     var name="局部";
4     return this.name;
5 };
6 alert(getName());

当this出现在全局环境的函数getName中时,此时函数getName运行时的位置在
alert(getName());

显然,函数getName所在的对象是全局对象,即window,因此this的安身之处定然在window。此时的this指向window对象,则getName返回的this.name其实是window.name,因此alert出来的是“全局”!
那么,当this不是出现在全局环境的函数中,而是出现在局部环境的函数中时,又会身陷何方呢?
1 var name="全局";
2 var twobin={
3     name:"局部",
4     getName:function(){
5         return this.name;
6     }
7 };
8 alert(twobin.getName());

其中this身处的函数getName不是在全局环境中,而是处在twobin环境中。无论this身处何处,一定要找到函数运行时的位置。此时函数getName运行时的位置
alert(twobin.getName());

显然,函数getName所在的对象是twobin,因此this的安身之处定然在twobin,即指向twobin对象,则getName返回的this.name其实是twobin.name,因此alert出来的是“局部”!
闭包中的this
闭包也是个不安分子,本文暂且不对其过于赘述,简而言之:所谓闭包就是在一个函数内部创建另一个函数,且内部函数访问了外部的变量。
浪子this与痞子闭包混在一起,可见将永无宁日啊!
 1 var name="全局";
 2 var twobin={
 3     name:"局部",
 4     getName:function(){
 5         return function(){
 6             return this.name;
 7         };
 8     }
 9 };
10 alert(twobin.getName()());

此时的this明显身处困境,竟然处在getName函数中的匿名函数里面,而该匿名函数又调用了变量name,因此构成了闭包,即this身处闭包中。
无论this身处何处,一定要找到函数运行时的位置。此时不能根据函数getName运行时的位置来判断,而是根据匿名函数的运行时位置来判断。
function (){
    return this.name;
};

显然,匿名函数所在的对象是window,因此this的安身之处定然在window,则匿名函数返回的this.name其实是window.name,因此alert出来的就是“全局”!
那么,如何在闭包中使得this身处在twobin中呢?
  var name="全局";
  var twobin={
      name:"局部",
      getName:function(){
          var that=this;
          return function(){
              return that.name;
          };
      }
 };
 alert(twobin.getName()());

在getName函数中定义that=this,此时getName函数运行时位置在
alert(twobin.getName());
则this指向twobin对象,因此that也指向twobin对象。在闭包的匿名函数中返回that.name,则此时返回的that.name其实是twobin.name,因此就可以alert出来 “局部”!
call与apply中的this
在JavaScript中能管的住this的估计也就非call与apply莫属了。
call与apply就像this的父母一般,让this住哪它就得住哪,不得不听话!
 var name="全局";
 var twobin={
name:"局部",
};
function getName(){
    alert(this.name);
}
getName(twobin);
getName.call(twobin);

其中this身处函数getName中。无论this身处何处,一定要找到函数运行时的位置。此时函数getName运行时的位置
getName(twobin);
显然,函数getName所在的对象是window,因此this的安身之处定然在window,即指向window对象,则getName返回的this.name其实是window.name,因此alert出来的是“全局”!
那么,该call与apply登场了,因为this必须听他们的指挥!
getName.call(twobin);
其中,call指定this的安身之处就是在twobin对象,因为this被迫只能在twobin那安家,则此时this指向twobin对象, this.name其实是twobin.name,因此alert出来的是“局部”!
一点总结
浪子this:永远指向函数运行时所在的对象,而不是函数被创建时所在的对象;如果处在匿名函数中或不处于任何对象中,则this指向window对象;如果是call或apply,它指定哪个对象,则this就指向哪个对象!
Javascript 相关文章推荐
js 格式化时间日期函数小结
Mar 20 Javascript
关于JS判断图片是否加载完成且获取图片宽度的方法
Apr 09 Javascript
Javascript 垃圾收集机制介绍理解
May 14 Javascript
js style动态设置table高度
Oct 21 Javascript
javascript中的正则表达式使用指南
Mar 01 Javascript
jQuery增加与删除table列的方法
Mar 01 Javascript
Angular.js回顾ng-app和ng-model使用技巧
Apr 26 Javascript
Node.js返回JSONP详解
May 18 Javascript
详谈js中标准for循环与foreach(for in)的区别
Nov 02 Javascript
浅谈js获取ModelAndView值的问题
Mar 28 Javascript
详解vue指令与$nextTick 操作DOM的不同之处
Aug 02 Javascript
vue-cli webpack配置文件分析
May 20 Javascript
jqGrid日期格式的判断示例代码(开始日期与结束日期)
Nov 08 #Javascript
JQuery验证jsp页面属性是否为空(实例代码)
Nov 08 #Javascript
原生js做的手风琴效果的导航菜单
Nov 08 #Javascript
jquery 日期控件datepicker属性详细解析
Nov 08 #Javascript
jquery增加时编辑jqGrid(实例代码)
Nov 08 #Javascript
jqueyr判断checkbox组的选中(示例代码)
Nov 08 #Javascript
iframe子父页面调用js函数示例
Nov 07 #Javascript
You might like
基于PHP magic_quotes_gpc的使用方法详解
2013/06/24 PHP
又一个PHP实现的冒泡排序算法分享
2014/08/21 PHP
PHP生成RSS文件类实例
2014/12/05 PHP
yii2.0之GridView自定义按钮和链接用法
2014/12/15 PHP
php+mysqli使用面向对象方式更新数据库实例
2015/01/29 PHP
php制作动态随机验证码
2015/02/12 PHP
PHP如何实现跨域
2016/05/30 PHP
PHP实现活动人选抽奖功能
2017/04/19 PHP
JavaScript 题型问答有答案参考
2010/02/17 Javascript
jQuery中add实现同时选择两个id对象
2010/10/22 Javascript
潜说js对象和数组
2011/05/25 Javascript
用jQuery中的ajax分页实现代码
2011/09/20 Javascript
Jquery动态改变图片IMG的src地址示例
2013/06/25 Javascript
JavaScript解析json格式数据简单示例
2014/12/09 Javascript
Jquery遍历Json数据的方法
2015/04/20 Javascript
Vue.JS入门教程之事件监听
2016/12/01 Javascript
JS简单实现点击按钮或文字显示遮罩层的方法
2017/04/27 Javascript
使用3D引擎threeJS实现星空粒子移动效果
2020/09/13 Javascript
Bootstrap 模态框多次显示后台提交多次BUG的解决方法
2017/12/26 Javascript
Rollup处理并打包JS文件项目实例代码
2018/05/31 Javascript
浅析TypeScript 命名空间
2020/03/19 Javascript
只有 20 行的 JavaScript 模板引擎实例详解
2020/05/11 Javascript
Django中实现一个高性能计数器(Counter)实例
2014/07/09 Python
Python3 能振兴 Python的原因分析
2014/11/28 Python
Python wxPython库Core组件BoxSizer用法示例
2018/09/03 Python
详解python中递归函数
2019/04/16 Python
利用python计算windows全盘文件md5值的脚本
2019/07/27 Python
简单了解python元组tuple相关原理
2019/12/02 Python
python3中datetime库,time库以及pandas中的时间函数区别与详解
2020/04/16 Python
巴西网上药房:onofre
2016/11/21 全球购物
美国地毯购买网站:Rugs USA
2019/02/23 全球购物
课内比教学心得体会
2014/09/09 职场文书
一年级小学生评语大全
2014/12/25 职场文书
少先队工作总结2015
2015/05/13 职场文书
2015民办小学年度工作总结
2015/05/26 职场文书
MySQL中TIMESTAMP类型返回日期时间数据中带有T的解决
2022/12/24 MySQL