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效果 slideToggle() 方法(在隐藏和显示之间切换)
Jun 28 Javascript
Json字符串转换为JS对象的高效方法实例
May 01 Javascript
jquery和雅虎的yql服务实现天气预报服务示例
Feb 08 Javascript
js类式继承与原型式继承详解
Apr 07 Javascript
js实现短信发送倒计时功能(正则验证)
Feb 10 Javascript
在vue中,v-for的索引index在html中的使用方法
Mar 06 Javascript
Vue项目中跨域问题解决方案
Jun 05 Javascript
vue-cli项目配置多环境的详细操作过程
Oct 30 Javascript
JavaScript实现的开关灯泡点击切换特效示例
Jul 08 Javascript
element-ui中按需引入的实现
Dec 25 Javascript
JavaScript 接口原理与用法实例详解
May 12 Javascript
Vue自定义全局弹窗组件操作
Aug 11 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 常用字符串函数总结
2008/03/15 PHP
PHP 杂谈《重构-改善既有代码的设计》之三 重新组织数据
2012/04/09 PHP
常见PHP数据库解决方案分析介绍
2015/09/24 PHP
php数组分页实现方法
2016/04/30 PHP
Laravel中批量赋值Mass-Assignment的真正含义详解
2017/09/29 PHP
Javascript 解疑
2009/11/11 Javascript
jquery高效反选具体实现
2013/05/05 Javascript
判断文件是否正在被使用的JS代码
2013/12/21 Javascript
JS替换文本域内的回车示例
2014/02/18 Javascript
Jquery自定义button按钮的几种方法
2014/06/11 Javascript
Javascript编程之继承实例汇总
2015/11/28 Javascript
Bootstrap 组件之按钮(二)
2016/05/11 Javascript
原生JS实现-星级评分系统的简单实例
2016/08/21 Javascript
微信小程序开发之入门实例教程篇
2017/03/07 Javascript
React Native 环境搭建的教程
2017/08/19 Javascript
highcharts 在angular中的使用示例代码
2017/09/20 Javascript
fullpage.js最后一屏滚动方式
2018/02/06 Javascript
JS实现键值对遍历json数组功能示例
2018/05/30 Javascript
layer关闭弹出窗口触发表单提交问题的处理方法
2019/09/25 Javascript
Vuex中实现数据状态查询与更改
2019/11/08 Javascript
[57:50]DOTA2上海特级锦标赛主赛事日 - 4 胜者组决赛Secret VS Liquid第二局
2016/03/05 DOTA
python实现udp数据报传输的方法
2014/09/26 Python
Python第三方库xlrd/xlwt的安装与读写Excel表格
2017/01/21 Python
Python中对象的引用与复制代码示例
2017/12/04 Python
python实现自动发送邮件
2018/06/20 Python
python正则表达式实例代码
2020/03/03 Python
基于ccs3的timeline时间线实现方法
2020/04/30 HTML / CSS
美国沃尔玛网上超市:Walmart
2020/08/14 全球购物
年会搞笑主持词串词
2014/03/24 职场文书
自我检讨报告
2015/01/28 职场文书
保研推荐信范文
2015/03/25 职场文书
酒店财务总监岗位职责
2015/04/03 职场文书
Django Paginator分页器的使用示例
2021/06/23 Python
mybatis中注解与xml配置的对应关系和对比分析
2021/08/04 Java/Android
CKAD认证中部署k8s并配置Calico插件
2022/03/31 Servers
解决flex布局中子项目尺寸不受flex-shrink限制
2022/05/11 HTML / CSS