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 空位补零实现代码
Feb 26 Javascript
基于jquery自定义图片热区效果
Jul 21 Javascript
页面图片浮动左右滑动效果的简单实现案例
Feb 10 Javascript
倒记时60刷新网页的js代码
Feb 18 Javascript
js判断手机和pc端选择不同执行事件的方法
Jan 30 Javascript
js文件中直接alert()中文出来的是乱码的解决方法
Nov 01 Javascript
微信小程序中input标签详解及简单实例
May 18 Javascript
解决Vue使用swiper动态加载数据,动态轮播数据显示白屏的问题
Sep 27 Javascript
详解Vue.js v-for不支持IE9的解决方法
Dec 29 Javascript
VUE 实现复制内容到剪贴板的两种方法
Apr 24 Javascript
为nuxt项目写一个面包屑cli工具实现自动生成页面与面包屑配置
Sep 29 Javascript
vue-i18n实现中英文切换的方法
Jul 06 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
输出控制类
2006/10/09 PHP
php SQL之where语句生成器
2009/03/24 PHP
PHP设计模式(九)外观模式Facade实例详解【结构型】
2020/05/02 PHP
prototype与jquery下Ajax实现的差别
2009/09/13 Javascript
ExtJS Ext.MessageBox.alert()弹出对话框详解
2010/04/02 Javascript
DOM_window对象属性之--clipboardData对象操作代码
2011/02/03 Javascript
formValidator3.3的ajaxValidator一些异常分析
2011/07/12 Javascript
Jquery阻止事件冒泡 event.stopPropagation
2011/12/11 Javascript
不提示直接关闭网页窗口的JS示例代码
2013/12/17 Javascript
jfinal与bootstrap的登录跳转实战演习
2015/09/22 Javascript
如何使用jquery easyui创建标签组件
2015/11/18 Javascript
javascript计时器编写过程与实现方法
2016/02/29 Javascript
基于Bootstrap3表格插件和分页插件实例详解
2016/05/17 Javascript
JavaScript地理位置信息API
2016/06/11 Javascript
jQuery用FormData实现文件上传的方法
2016/11/21 Javascript
js实现各浏览器全屏代码实例
2018/07/03 Javascript
JavaScript实现无限级递归树的示例代码
2019/03/29 Javascript
JS块级作用域和私有变量实例分析
2019/05/11 Javascript
javascript设计模式 ? 职责链模式原理与用法实例分析
2020/04/16 Javascript
微信小程序自定义弹出层效果
2020/05/26 Javascript
[01:10]DOTA2 Supermajor:英雄,由我们见证
2018/05/14 DOTA
[43:14]Liquid vs Optic 2018国际邀请赛淘汰赛BO3 第二场 8.21
2018/08/22 DOTA
Python实现去除图片中指定颜色的像素功能示例
2019/04/13 Python
Django 缓存配置Redis使用详解
2019/07/23 Python
python pycharm的安装及其使用
2019/10/11 Python
Python实现对adb命令封装
2020/03/06 Python
Manuka Doctor美国官网:麦卢卡蜂蜜和蜂毒护肤
2016/12/25 全球购物
美国高档百货Nordstrom的折扣店:Nordstrom Rack
2017/11/13 全球购物
英国最大的独立玩具专卖店:The Entertainer
2019/09/06 全球购物
在weblogic中发布ejb需涉及到哪些配置文件
2012/01/17 面试题
《美丽的公鸡》教学反思
2014/02/25 职场文书
护士个人年终总结
2015/02/13 职场文书
小学英语教师研修感悟
2015/11/18 职场文书
MySQL性能压力基准测试工具sysbench的使用简介
2021/04/21 MySQL
Redis入门教程详解
2021/08/30 Redis
Spring Boot实现文件上传下载
2022/08/14 Java/Android