在JavaScript开发中,this是很常用的一个关键字,但同时也是一个很容易引入bug的一个关键字,在这里我们就专门总结一下页面中可能出现的this关键字(包括几种在其他页面文件中出现的this)。
  JavaScript中的this关键字通常只使用在函数中,它指向当前函数的调用者,这是this关键字的本质,所有的使用方式都是围绕这个展开的,让我们来看一下在各种性质的函数中this的用法。
1. 在对象的函数中使用this

var person = {
name: 'Frank',
say: function() {
alert(this.name);
}
};
person.say();

  这是常用的情况,this指向当前函数的调用者,就是对象本身。

2. 在构造函数中使用的this

function Person(name) {
this.name = name;
this.say = function() {
alert(this.name);
};
}
var p1 = new Person('Frank');
p1.say();

  这也是常用情况,在前面分析new的时候,我们就知道this指向新构造的对象,因为这个新对象是函数的调用者。
  这里还有一个情况,那就是在上面的代码下面加上下面的代码:

var foo = p1.say;
foo();

  你能根据this总是指向函数调用者的原理得到输出的结果吗?注意此时say方法不再是用p1去调用了,而是直接在全局调用。
  由于函数是JavaScript的基本数据类型之一,一旦函数在不同的变量之间传递了,那么函数中使用的this就可能指向不同的对象了。所以很多的时候,函数的赋值会导致一些隐藏很深的bug,这一点值得大家注意。

3. 使用call/apply方式调用的函数中的this

var obj = {
x: 20;
f: function(){ alert(this.x); }
}; var obj2 = {
x: 30;
}; obj1.f.call(obj2); //利用call指派f的this指向obj2,故输出30

  这种情况是直接修改函数的调用者,于是this指向传入的第一个参数。

4. 在HTML元素的事件中inline方式使用的this

<div id="testDiv" onclick="alert(this)">Click Me!</div>

结果是输出:[object HTMLDivElement]
  这种情况下,由于是HTML元素触发的事件,所以this当然指向HTML元素对应的JavaScript对象。

5. 在HTML元素的回调函数中出现的this

<script type="text/javascript">
function demo() {
alert(this);
}
</script>
<div id="testDiv" onclick="demo()">Click Me!</div>

结果是输出:[object Window]
  这种情况下,由于回调函数是在JavaScript中执行的,所以this指向全局对象window。

6. 在DOM中指定的回调函数中出现的this

<div id="testDiv">Click Me!</div>
<script language="javascript">
var div = document.getElementById('testDiv');
div.onclick = function() {
alert(this);
};
</script>

结果是输出:[object HTMLDivElement]
  这种情况下,由于回调函数是赋值给div对象去回调的,所以this指向div对象。当然了在Jquery的回调函数中使用this,也是指向Jquery生成的Jquery元素对象。例如:

$("#testDiv").click(function() {
alert(this);
});

  特别注意这种情况与上一个例子的不同。当然在回调函数中,我们大部分情况都需要获得触发事件的div对象,我们可以结合第4种情况,把this作为参数传给回调函数:

<script type="text/javascript">
function demo(target) {
alert(target);
}
</script>
<div id="testDiv" onclick="demo(this)">Click Me!</div>

结果是输出:[object HTMLDivElement]

7. CSS的expression表达式中使用的this

<div style="width: expression(this.parentElement.width); height: expression(this.parentElement.height);">Click Me!</div>

  由于这是在div对象本身去调用这些表达式去设置style,这里的this也是指代div元素对象本身。

8. 闭包函数中的this

<div id="testDiv">Click Me!</div>
<script language="javascript">
var div = document.getElementById('testDiv');
div.onclick = function() {
alert(this);
(function() {
alert(this);
})();
};
</script>

结果是输出:[object HTMLDivElement]与[object Window]。
  很显然,大多数情况下,我们希望第二个this仍然指向div对象,我们可以如下实现:

<div id="testDiv">Click Me!</div>
<script language="javascript">
var div = document.getElementById('testDiv');
div.onclick = function() {
alert(this);
var that = this;
(function() {
alert(that);
})();
};
</script>

  使用普通变量保护某一个时刻this指向的对象是解决闭包里面类似问题的常见方式。

9. 直接在全局作用域中使用的this
  这是一种不常见的情况,但是确实存在,这个时候this指向全局对象window (在node.js中,则为GLOBAL对象)。例如:

var x = 10;
alert(x);
alert(this.x);
alert(window.x);
alert(this); // 输出[object Window]

10. 直接在不当作构造函数的函数中使用的this
  这种情况也不常见,由于是在全局调用这个方法,this此时指向全局对象window,但是在严格模式中,则是undefined。。例如:

function foo() {
alert(this);
} foo(); // 输出[object Window]

  常见的使用this的就是这么多了,其他的情况可根据类似的案例进行分析。

JavaScript大杂烩6 - 理解JavaScript中的this的更多相关文章

  1. JavaScript大杂烩1 - 理解JavaScript的类型系统

    随着硬件水平的逐渐提高,浏览器的处理能力越来越强大,本人坚信,客户端会越来越瘦,瘦到只用浏览器就够了,服务端会越来越丰满:虽然很多大型的程序,比如3D软件,客户端仍然会存在,但是未来的主流必将是浏览器 ...

  2. JavaScript大杂烩4 - 理解JavaScript对象的继承机制

    JavaScript是单根的完全面向对象的语言 JavaScript是单根的面向对象语言,它只有单一的根Object,所有的其他对象都是直接或者间接的从Object对象继承.而在JavaScript的 ...

  3. JavaScript大杂烩3 - 理解JavaScript对象的封装性

    JavaScript是面向对象的 JavaScript是一种基于对象的语言,你遇到的所有东西,包括字符串,数字,数组,函数等等,都是对象. 面向过程还是面向对象? JavaScript同时兼有的面向过 ...

  4. JavaScript大杂烩2 - 理解JavaScript的函数

    JavaScript中的字面量 书接上回,我们已经知道在JavaScript中存在轻量级的string,number,boolean与重量级的String,Number,Boolean,而且也知道了之 ...

  5. JavaScript大杂烩12 - 理解Ajax

    AJAX缘由 再次谈起这个话题,我深深的记得就在前几年,AJAX被炒的如火如荼,就好像不懂AJAX,就不会Web开发一样.要理解AJAX为什么会出现,就要先了解Web开发面临的问题. 我们先来回忆一下 ...

  6. 深入理解JavaScript系列+ 深入理解javascript之执行上下文

    http://www.cnblogs.com/TomXu/archive/2011/12/15/2288411.html http://blog.csdn.net/hi_kevin/article/d ...

  7. JavaScript大杂烩11 - 理解事件驱动

    前面我们回顾了前端JavaScript只干的两件事:操作BOM与操作DOM,那么什么时候去干这些事呢?答案是需要干的时候去干.那么什么时候是需要干的时候呢?答案是事件被触发的时候.这就是通常所说的“事 ...

  8. JavaScript大杂烩10 - 理解DOM

    操作DOM 终于到了JavaScript最为核心的部分了,通常来说,操作DOM,为页面提供更为友好的行为是JavaScript根本目标.   DOM树 - HTML结构的抽象 既然DOM是操纵HTML ...

  9. JavaScript大杂烩9 - 理解BOM

    毫无疑问,我们学习JavaScript是为了完成特定的功能.在最初的JavaScript类型系统中,我们已经分析过JavaScript在页面开发中充当着添加逻辑的角色,而且我们知道JavaScript ...

随机推荐

  1. LeetCode手记-Add Binary

    问题描述 问题分析 分析题意,此题实际是求解两个二进制数的和,但是有两点要注意: 1.字符串的长度不限,所以相应十进制数值很可能会超过int的上限. 2.二进制的加法规则是自右向左进位,需要注意,以题 ...

  2. UFLDL 教程学习笔记(一)神经网络

    UFLDL(Unsupervised Feature Learning and Deep Learning)Tutorial 是由 Stanford 大学的 Andrew Ng 教授及其团队编写的一套 ...

  3. Django--cookie操作

    day74 会话跟踪技术 什么是会话跟踪 我们需要先了解一下什么是会话!可以把会话理解为客户端与服务器之间的一次会晤,在一次会晤中可能会包含多次请求和响应.例如你给10086打个电话,你就是客户端,而 ...

  4. Django--CSRF 跨站请求伪造

    一.简介 django为用户实现防止跨站请求伪造的功能,通过中间件 django.middleware.csrf.CsrfViewMiddleware 来完成.而对于django中设置防跨站请求伪造功 ...

  5. 从零开始学 Web 之 Ajax(一)服务器相关概念

    大家好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公众号:Web前端之巅 博客园:ht ...

  6. TCP/IP 笔记 - 超时和重传

    TCP协议为了提供可靠的数据传输服务,会启动数据重传来解决下层网络层(IP)可能出现的数据包丢失. 超时重传介绍 TCP重传由两套独立机制来完成重传,基于时间的超时重传(RTO,TCP发送数据时会设置 ...

  7. 我们自研的那些Devops工具

    随着云技术以及容器技术的崛起,人肉运维的时代结束了 2018年为了解决日常运维中的痛点以及更高效的推进运维工作,我们自研并完善了几个工具系统,这些系统无一例外的帮我们节约了时间,提高了效率,这篇文章将 ...

  8. Java并发编程笔记之 CountDownLatch闭锁的源码分析

    JUC 中倒数计数器 CountDownLatch 的使用与原理分析,当需要等待多个线程执行完毕后在做一件事情时候 CountDownLatch 是比调用线程的 join 方法更好的选择,CountD ...

  9. leetcode — generate-parentheses

    import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * Source : https://o ...

  10. BizTalk 2010/2013 EDI B2B项目实践(1)

    BizTalk 2010/2013 EDI B2B项目实践(1) BizTalk开发标准EDI B2B是件非常容易的事情,但对于初学者可能有很多专业术语不太理解,不知道如何下手,我之前开始学的时候虽然 ...