灵活的理解JavaScript中的this指向(一)
this是JavaScript中的关键字之一,在编写程序的时候经常会用到,正确的理解和使用关键字this尤为重要。首先必须要说的是,this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象(这句话有些问题,后面会解释为什么会有问题,虽然网上大部分的文章都是这样说的,虽然在很多情况下那样去理解不会出什么问题,但是实际上那样理解是不准确的,所以在你理解this的时候会有种琢磨不透的感觉),那么接下来我会深入的探讨这个问题。
为什么要学习this?如果你学过函数式编程,面向对象编程,那你肯定知道干什么用的,如果你没有学过,那么暂时可以不用看这篇文章,当然如果你有兴趣也可以看看,毕竟这是js中必须要掌握的东西。
例子1:
|
1
2
3
4
5
6
|
function a(){var user = "Tiger";console.log(this.user); //undefinedconsole.log(this); //Window}a(); |
按照我们上面说的this最终指向的是调用它的对象,这里的函数a实际是被Window对象所点出来的,下面的代码就可以证明。
|
1
2
3
4
5
6
|
function a(){var user = "Tiger";console.log(this.user); //undefinedconsole.log(this); //Window}window.a(); |
和上面代码一样吧,其实alert也是window的一个属性,也是window点出来的。
例子2:
|
1
2
3
4
5
6
7
|
var o = {user:"Tiger",fn:function(){console.log(this.user); //Tiger}}o.fn(); |
这里的this指向的是对象o,因为你调用这个fn是通过o.fn()执行的,那自然指向就是对象o,这里再次强调一点,this的指向在函数创建的时候是决定不了的,在调用的时候才能决定,谁调用的就指向谁,一定要搞清楚这个。
其实例子1和例子2说的并不够准确,下面这个例子就可以推翻上面的理论。
如果要彻底的搞懂this必须看接下来的几个例子
例子3:
|
1
2
3
4
5
6
7
|
var o = {user:"Tiger",fn:function(){console.log(this.user); //Tiger}}window.o.fn(); |
这段代码和上面的那段代码几乎是一样的,但是这里的this为什么不是指向window,如果按照上面的理论,最终this指向的是调用它的对象,这里先说个而外话,window是js中的全局对象,我们创建的变量实际上是给window添加属性,所以这里可以用window点o对象。
这里先不解释为什么上面的那段代码this为什么没有指向window,我们再来看一段代码。
|
1
2
3
4
5
6
7
8
9
10
|
var o = {a:10,b:{a:12,fn:function(){console.log(this.a); //12}}}o.b.fn(); |
这里同样也是对象o点出来的,但是同样this并没有执行它,那你肯定会说我一开始说的那些不就都是错误的吗?其实也不是,只是一开始说的不准确,接下来我将补充一句话,我相信你就可以彻底的理解this的指向的问题。
情况1:如果一个函数中有this,但是它没有被上一级的对象所调用,那么this指向的就是window,这里需要说明的是在js的严格版中this指向的不是window,但是我们这里不探讨严格版的问题,你想了解可以自行上网查找。
情况2:如果一个函数中有this,这个函数有被上一级的对象所调用,那么this指向的就是上一级的对象。
情况3:如果一个函数中有this,这个函数中包含多个对象,尽管这个函数是被最外层的对象所调用,this指向的也只是它上一级的对象,例子3可以证明,如果不相信,那么接下来我们继续看几个例子。
|
1
2
3
4
5
6
7
8
9
10
|
var o = {a:10,b:{// a:12,fn:function(){console.log(this.a); //undefined}}}o.b.fn(); |
尽管对象b中没有属性a,这个this指向的也是对象b,因为this只会指向它的上一级对象,不管这个对象中有没有this要的东西。
还有一种比较特殊的情况,例子4:
|
1
2
3
4
5
6
7
8
9
10
11
12
|
var o = {a:10,b:{a:12,fn:function(){console.log(this.a); //undefinedconsole.log(this); //window}}}var j = o.b.fn;j(); |
这里this指向的是window,是不是有些蒙了?其实是因为你没有理解一句话,这句话同样至关重要。
this永远指向的是最后调用它的对象,也就是看它执行的时候是谁调用的,例子4中虽然函数fn是被对象b所引用,但是在将fn赋值给变量j的时候并没有执行所以最终指向的是window,这和例子3是不一样的,例子3是直接执行了fn。
this讲来讲去其实就是那么一回事,只不过在不同的情况下指向的会有些不同,上面的总结每个地方都有些小错误,也不能说是错误,而是在不同环境下情况就会有不同,所以我也没有办法一次解释清楚,只能你慢慢地的去体会。
构造函数版this:
|
1
2
3
4
5
|
function Fn(){this.user = "Tiger";}var a = new Fn();console.log(a.user); //Tiger |
这里之所以对象a可以点出函数Fn里面的user是因为new关键字可以改变this的指向,将这个this指向对象a,为什么我说a是对象,因为用了new关键字就是创建一个对象实例,理解这句话可以想想我们的例子3,我们这里用变量a创建了一个Fn的实例(相当于复制了一份Fn到对象a里面),此时仅仅只是创建,并没有执行,而调用这个函数Fn的是对象a,那么this指向的自然是对象,那么为什么对象Fn中会有user,因为你已经复制了一份Fn函数到对象a中,用了new关键字就等同于复制了一份。
除了上面的这些以外,我们还可以自行改变this的指向,关于自行改变this的指向请看JavaScript中call,apply,bind方法的总结这篇文章,详细的说明了我们如何手动更改this的指向。
灵活的理解JavaScript中的this指向(一)的更多相关文章
- Javascript中的this指向。
一.JavaScript中的函数 在了解this指向之前,要先弄明白函数执行时它的执行环境是如何创建的,这样可以更清楚的去理解JavaScript中的this指向. function fn(x,y,n ...
- 深入理解JavaScript中创建对象模式的演变(原型)
深入理解JavaScript中创建对象模式的演变(原型) 创建对象的模式多种多样,但是各种模式又有怎样的利弊呢?有没有一种最为完美的模式呢?下面我将就以下几个方面来分析创建对象的几种模式: Objec ...
- 转载 深入理解JavaScript中的this关键字
转载原地址: http://www.cnblogs.com/rainman/archive/2009/05/03/1448392.html 深入理解JavaScript中的this关键字 1. 一 ...
- 理解 JavaScript 中的 this
前言 理解this是我们要深入理解 JavaScript 中必不可少的一个步骤,同时只有理解了 this,你才能更加清晰地写出与自己预期一致的 JavaScript 代码. 本文是这系列的第三篇,往期 ...
- 全面理解JavaScript中的 this
全面理解JavaScript中的 this 上下文 VS 作用域 作用域(scope) 是在运行时代码中的某些特定部分中变量,函数和对象的可访问性.换句话 说,作用域决定了代码区块中变量和其他资源的可 ...
- JavaScript中 this 的指向
很多人都会被JavaScript中this的指向(也就是函数在调用时的调用上下文)弄晕,这里做一下总结: 首先,顶层的this指向全局对象. 函数中的this按照调用方法的不同,其指向也不同: 1.函 ...
- 理解javascript中的回调函数(callback)【转】
在JavaScrip中,function是内置的类对象,也就是说它是一种类型的对象,可以和其它String.Array.Number.Object类的对象一样用于内置对象的管理.因为function实 ...
- 深入理解 JavaScript 中的 class
在 ES6 规范中,引入了 class 的概念.使得 JS 开发者终于告别了,直接使用原型对象模仿面向对象中的类和类继承时代. 但是JS 中并没有一个真正的 class 原始类型, class 仅仅只 ...
- 如何理解JavaScript中的函数
转: 如何理解JavaScript中的函数 JS中的函数简介 JS中的函数是一种通过调用来完成具体业务的一段代码块.最核心的目的是将可重复执行的操作进行封装,然后供调用方无限制的调用. JS中的函数的 ...
随机推荐
- 【NOIP2012模拟8.20】Memory
题目 话说某一天,CD在爬树的时候发现了树干上有一大串奇怪的符文,于是好奇的CD就从头到尾看了一遍.看完一遍以后CD觉得,最后一段文字好像很眼熟,好像在前面见过.对于CD来说,一开始看到的符文会印象特 ...
- 【leetcode】1123. Lowest Common Ancestor of Deepest Leaves
题目如下: Given a rooted binary tree, return the lowest common ancestor of its deepest leaves. Recall th ...
- HTML中的表单<form>标签
一.HTML表单 HTML 表单用于搜集不同类型的用户输入. HTML 表单包含表单元素,表单元素指的是不同类型的 input 元素.复选框.单选按钮.提交按钮等等. 关于表单的更多内容可以参考htt ...
- 事物 @Transactional
转载:http://www.cnblogs.com/kristain/articles/2038397.html 一.什么是事务 事务是访问数据库的一个操作序列,数据库应用系统通过事务集来完成对数据库 ...
- 6.12友谊赛T4城市交通费题解
与普通的最短路径不同的是,题目中新引入了一个计入总体的费用——城市建设费.由于城市建设费由整体的某最大值决定,导致解没有最优子结构的性质,给思维带来难度. 既然最棘手的是城市建设费,我们就对它分类讨论 ...
- RabbitMQ消息如何100%投递成功(六)
消息如何保障100%的投递成功? 什么是生产端的可靠性投递? 保障消息的成功发出 保障MQ节点的成功接收 发送端收到MQ节点(Broker)确认应答 完善的消息进行补偿机制(如网络问题没有返回确认应答 ...
- [CSP-S模拟测试]:寿司(暴力)
题目描述 小$c$是一名$oier$.最近,他发现他的数据结构好像学傻了.因为他在刷题时碰到了一道傻逼数据结构题,强行使用了平衡树来解决,卡着时间$AC$.为此,他被狠狠地嘲讽了一番.于是,小$c$找 ...
- Fabric基础架构原理(一)
Linux基金会于2015年12月启动了名为“超级账本”(Hyperledger)的开源项目,旨在推动各方协作,共同打造基于区块链的企业级分布式账本底层技术,用于构建支撑业务的行业应用和平台. 超级账 ...
- php 判断访问是否是手机或者pc
php代码 function isMobile() { $user_agent = $_SERVER['HTTP_USER_AGENT']; $mobile_agents = Array(" ...
- 任何国家都无法限制数字货币。为什么呢? 要想明白这个问题需要具备一点区块链的基础知识: 区块链使用的大致技术包括以下几种: a.点对点网络设计 b.加密技术应用 c.分布式算法的实现 d.数据存储技术 e.拜占庭算法 f.权益证明POW,POS,DPOS 原因一: 点对点网络设计 其中点对点的P2P网络是bittorent ,由于是点对点的网络,没有中心化,因此在全球分布式的网
任何国家都无法限制数字货币.为什么呢? 要想明白这个问题需要具备一点区块链的基础知识: 区块链使用的大致技术包括以下几种: a.点对点网络设计 b.加密技术应用 c.分布式算法的实现 d.数据存储技 ...