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 相关文章推荐
jquery.validate使用攻略 第一部
Jul 01 Javascript
jQuery代码优化之基本事件
Nov 01 Javascript
JSON为什么那样红为什么要用json(另有洞天)
Dec 26 Javascript
前台js对象在后台转化java对象的问题探讨
Dec 20 Javascript
node中socket.io的事件使用详解
Dec 15 Javascript
原生JavaScript实现异步多文件上传
Dec 02 Javascript
JavaScript简单实现弹出拖拽窗口(一)
Jun 17 Javascript
AngularJS标签页tab选项卡切换功能经典实例详解
May 16 Javascript
基于vue实现可搜索下拉框定制组件
Mar 26 Javascript
vue3.0中的双向数据绑定方法及优缺点
Aug 01 Javascript
vue如何使用模拟的json数据查看效果
Mar 31 Vue.js
uniapp引入支付宝原生扫码插件步骤详解
Jul 23 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实现微信退款功能
2018/10/02 PHP
jQuery温习篇 强大的JQuery选择器
2010/04/24 Javascript
分享精心挑选的23款美轮美奂的jQuery 图片特效插件
2012/08/14 Javascript
在js中判断checkboxlist(.net控件客户端id)是否有选中
2013/04/11 Javascript
jQuery中选择器小问题(新人难免遇到)
2014/03/31 Javascript
JS比较2个日期间隔的示例代码
2014/04/15 Javascript
arguments对象验证函数的参数是否合法
2015/06/26 Javascript
javascript实现鼠标移到Image上方时显示文字效果的方法
2015/08/07 Javascript
jQuery随手笔记之常用的jQuery操作DOM事件
2015/11/29 Javascript
基于JS实现弹出一个隐藏的div窗口body页面变成灰色并且不可被编辑
2016/12/14 Javascript
原生js实现焦点轮播图效果
2017/01/12 Javascript
H5手机端多文件上传预览插件
2017/04/21 Javascript
详解微信小程序中的页面代码中的模板的封装
2017/10/12 Javascript
vue项目开发中setTimeout等定时器的管理问题
2018/09/13 Javascript
详解Webpack loader 之 file-loader
2018/11/07 Javascript
JavaScript判断对象和数组的两种方法
2019/05/31 Javascript
jQuery实现tab栏切换效果
2020/12/22 jQuery
[01:37]DOTA2超级联赛专访ChuaN 传奇般的电竞之路
2013/06/19 DOTA
[04:04]显微镜下的DOTA2第六期——电影级别的华丽团战
2014/06/20 DOTA
Python实现PS滤镜的旋转模糊功能示例
2018/01/20 Python
python requests 库请求带有文件参数的接口实例
2019/01/03 Python
对python numpy.array插入一行或一列的方法详解
2019/01/29 Python
python利用JMeter测试Tornado的多线程
2020/01/12 Python
tensorflow:指定gpu 限制使用量百分比,设置最小使用量的实现
2020/02/06 Python
Python函数生成器原理及使用详解
2020/03/12 Python
Django 允许局域网中的机器访问你的主机操作
2020/05/13 Python
美国鞋类购物网站:Shiekh Shoes
2016/08/21 全球购物
销售行业个人求职自荐信
2013/09/25 职场文书
个人求职信范例
2014/01/29 职场文书
化妆品店促销方案
2014/02/24 职场文书
群众路线查摆问题及整改措施
2014/10/10 职场文书
培根随笔读书笔记
2015/07/01 职场文书
小学运动会通讯稿
2015/07/18 职场文书
初中同学会致辞
2015/08/01 职场文书
医学生自荐信范文(2016精选篇)
2016/01/28 职场文书
Spring Data JPA框架持久化存储数据到数据库
2022/04/28 Java/Android