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 相关文章推荐
javascript闭包的理解和实例
Aug 12 Javascript
使用jQuery和PHP实现类似360功能开关效果
Feb 12 Javascript
IE中getElementsByName()对有些元素无效的解决方案
Sep 28 Javascript
使用jquery插件qrcode生成二维码
Oct 22 Javascript
js实现动态创建的元素绑定事件
Jul 19 Javascript
Angular2 Service实现简单音乐播放器服务
Feb 24 Javascript
jquery tmpl模板(实例讲解)
Sep 02 jQuery
用Vue写一个分页器的示例代码
Apr 22 Javascript
vue2.0 自定义组件的方法(vue组件的封装)
Jun 05 Javascript
node.js命令行教程图文详解
May 27 Javascript
vue项目中使用AES实现密码加密解密(ECB和CBC两种模式)
Aug 12 Javascript
js实现随机抽奖
Mar 19 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 中文字符入库或显示乱码问题的解决方法
2010/04/12 PHP
php定时删除文件夹下文件(清理缓存文件)
2013/01/23 PHP
ThinkPHP中公共函数路径和配置项路径的映射分析
2014/11/22 PHP
详解PHP对数组的定义以及数组的创建方法
2015/11/27 PHP
PHP反射机制原理与用法详解
2017/02/15 PHP
php大小写转换函数(strtolower、strtoupper)用法介绍
2017/11/17 PHP
thinkphp3.2同时连接两个数据库的简单方法
2019/08/13 PHP
JavaScript 创建对象和构造类实现代码
2009/07/30 Javascript
javascript preload&lazy load
2010/05/13 Javascript
JavaScript中__proto__与prototype的关系深入理解
2012/12/04 Javascript
js中数组Array的一些常用方法总结
2013/08/12 Javascript
JavaScript中九种常用排序算法
2014/09/02 Javascript
浅谈$(document)和$(window)的区别
2015/07/15 Javascript
JavaScript的React框架中的JSX语法学习入门教程
2016/03/05 Javascript
JavaScript重载函数实例剖析
2016/05/13 Javascript
jQuery UI Bootstrap是什么?
2016/06/17 Javascript
通俗易懂地解释JS中的闭包
2017/10/23 Javascript
vue2 mint-ui loadmore实现下拉刷新,上拉更多功能
2018/03/21 Javascript
详解Angular路由之路由守卫
2018/05/10 Javascript
nodejs 简单实现动态html的方法
2018/05/12 NodeJs
js中时间格式化的几种方法
2018/07/22 Javascript
使用Node.js写一个代码生成器的方法步骤
2019/05/10 Javascript
Vue触发input选取文件点击事件操作
2020/08/07 Javascript
对于Python异常处理慎用“except:pass”建议
2015/04/02 Python
使用50行Python代码从零开始实现一个AI平衡小游戏
2018/11/21 Python
python配置grpc环境
2019/01/01 Python
Python 中判断列表是否为空的方法
2019/11/24 Python
Tensorflow的梯度异步更新示例
2020/01/23 Python
Pytorch maxpool的ceil_mode用法
2020/02/18 Python
Python3.x+pyqtgraph实现数据可视化教程
2020/03/14 Python
软件工程师岗位职责
2013/11/16 职场文书
公司年会主持词
2014/03/22 职场文书
写字楼租赁意向书
2014/07/30 职场文书
投诉书范文
2015/07/02 职场文书
红白喜事主持词
2015/07/06 职场文书
Java实现给Word文件添加文字水印
2022/02/15 Java/Android