this到底指向哪里

this指向调用它的对象

首先要明确,this指向调用方,谁调用,this指向谁。

直接调用

举个栗子:

var test = 'window'
;
function testThis () {var test = 'inner';this.test = 'test change';console.log(this.test)
}
testThis(); // test change
console.log(window.test) // test change

在chrome中执行后可以发现,外部挂在window下的test被修改了,因为这个testThis的函数,是被window调用的,它只会读取window下的test。

构造函数调用

再举个栗子:

var test = 'window'
;
function testThis () {var test = 'inner';console.log(this.test)this.test = 'test change';console.log(this.test)
}
var newTestThis = new testThis(); 
// undefined
// test change
console.log(window.test) // window

在chrome中执行以下可以发现,依次输出undefined、test change、window。
这个栗子与上面的区别在于调用了new。此时,该函数作为构造函数调用,我们都知道,构造函数中的this都指向new出来的对象。所以this指向了这个新生成的newTestThis。自然地,window下test就没有被修改。

嵌套调用

接下来举一个栗子,来说明在函数嵌套调用时的this指向:

var x = 'global'
function testThis () {// this.x = 'fuck';// console.log(this)console.log(this.x)
}
function innerObj () {this.x = 'inner';testThis();this.innerTestThis = testThis;this.innerTestThis();
}function wrapObj () {this.x = 'wrap';// var test = new testThis();// console.log(test.x)testThis();this.wrapTestThis = testThis;this.wrapTestThis();this.innerTestThis = new innerObj();
}
var wrap = new wrapObj();
wrapObj();
// global
// wrap
// global
// inner
// wrap
// wrap
// wrap
// inner

很明显,在函数嵌套时,如果不给函数指定调用对象,则不论被调用函数是在哪个函数的作用域里,被调用的函数的this都是指向window的。
我们可以这样理解,在直接调用时,这些函数除了拥有自己的作用域外,就像是把这几行代码写到了相应的位置。可以想一下,所有的js代码最后都拼到一起,很明显,他们的调用方都是window。

总结一下:1.不论函数在哪里被调用,只要没有指定调用方,则this都指向window。指定了调用方,就指向调用方。2.作为构造函数中调用,this指向新生成的对象。

分析一下:setTimeout和setInterval

bind的作用就是给函数一个指定的thisArg,经常使用bind的地方就是setTimeout和setInterval了。为什么呢?
setTimeout和setInterval都有一个特点,它会将回调函数的作用域转移到window上面。其实结合我们上面说的,很容易知道为什么。
以setTimeout为例:翻看MDN下setTimeout的定义,可以发现,setTimeout是把一段callback代码延迟执行。写过callback的同学都知道,callback的代码其实就是占了位,然后去调用一行行的代码,所以,callback中的this也会指向window。
实际开发中,我们不希望this指向window,故而常使用bind来使this指向我们希望的对象。

bind、apply、call

说到了bind,就还需要提一下另外的可以改变this指向的方法:apply和call。
这两个函数大同小异,只是传参有区别。不论使用apply还是call,都会传入一个thisArg,作为函数调用方,让函数中的this指向thisArg。
在下一篇,我会介绍一下apply和call。


更多专业前端知识,请上 【猿2048】www.mk2048.com

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/362897.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

GA,RC,Alpha,Beta,Final等软件版本名词释义

对应上图的表格如下: 名词!说明Alphaα是希腊字母的第一个,表示最早的版本,内部测试版,一般不向外部发布,bug会比较多,功能也不全,一般只有测试人员使用。Betaβ是希腊字母的第二个&…

HawtIO在JBoss EAP上(第二部分)

我刚刚发布了一篇关于在JBoss Wildfly 8.1上运行HawtIO的条目 。 从那篇文章中,您将了解HawtIO多么出色 ,以及它必须具备的所有 出色 插件,才能从单个仪表板管理基于JVM的技术……好吧…… hawt ……。 但是,出于上一篇文章中概述…

Linux命令行中执行多个命令

[rootlocalhost /]# date;date;date 2019年 05月 03日 星期五 09:08:37 CST 2019年 05月 03日 星期五 09:08:37 CST 2019年 05月 03日 星期五 09:08:37 CST [rootlocalhost /]# date&& data&&date 2019年 05月 03日 星期五 09:09:03 CST -bash: data: 未找到命…

JS设计模式(13)状态模式

什么是状态模式? 定义:将事物内部的每个状态分别封装成类,内部状态改变会产生不同行为。 主要解决:对象的行为依赖于它的状态(属性),并且可以根据它的状态改变而改变它的相关行为。 何时使用…

Save info in Hidden Field

Hidden fields are used to store data at the page level protected System.Web.UI.HtmlControls.HtmlInputHidden Hidden1; //to assign a value to Hidden field Hidden1.Value"Create hidden fields"; //to retrieve a value string strHidden1.Value; 转载于:ht…

课堂测试

package 测试;import java.util.Scanner;class ScoreInformation {private String stunumber;private String name;private double mathematicsscore;private double englishiscore;private double networkscore;private double databasescore;private double softwarescore;…

Mule ESB,ActiveMQ和DLQ

在本文中,我将展示一个简单的Mule ESB流程,以了解实际中使用的Active MQ 的DLQ功能 。 我假设您有一个正在运行的Apache ActiveMQ实例(如果没有,则可以在此处下载一个版本)。 在此示例中,我使用了Mule ESB…

JS设计模式(2)策略模式

什么是策略模式? 定义:根据不同参数可以命中不同的策略 主要解决:在有多种算法相似的情况下,使用 if...else 所带来的复杂和难以维护。 何时使用:有许多种情况,而区分它们的只是他们直接的行为。 如何解…

C#中使用多线程访问Winform问题解决方案

我们在做winform应用的时候,大部分情况下都会碰到使用多线程控制界面上控件信息的问题。然而我们并不能用传统方法来做这个问题,下面我将详细的介绍。 首先来看传统方法: public partial class Form1 : Form{public Form1(){InitializeCompon…

Choose and Divide UVa 10375

题目大意:给出p,q,r,s,求组合数C(p,q)/C(r,s) 题目思路: 化简得到:原式等价于(p!(r-s)!s!) / (r!(p-q)!q!) 由算数基本定理可知任意一个正整数可被唯一分解为素数幂乘积的形式,将分子分母分解后,进行约分即…

在Java中避免空检查

对于Java开发人员(从初级到专家)最糟糕的噩梦之一是空对象引用检查。 我很确定您已经看过几次这样的代码: public void addAddressToCustomer(Customer customer, Address newAddress){if ( cutomer null || newAddress null)return;if ( …

Linux sudo 详解

简单的说,sudo 是一种权限管理机制,管理员可以授权于一些普通用户去执行一些 root 执行的操作,而不需要知道 root 的密码。严谨些说,sudo 允许一个已授权用户以超级用户或者其它用户的角色运行一个命令。当然,能做什么…

echarts自定义图例legend文字和样式

话不多说,先上效果图。 要完成这个图并不难,主要是下面那个图例比较难,需要定制。 让我们从官方文档找找思路,官方文档关于legend.formatter是这样的:链接在这 难点在于: 1.这里的图例文本包含两个变量&am…

DataGridView常见用法和FAQ汇总

前段时间在项目中用到了WinForm,其中最复杂的控件当属DataGridView了,特别喜欢它那高度的可配置性(提供了大量的属性,方法和事件)、丰富的内置列类型,而且易于扩展,对性能问题也提供了良好的解决方案。不过最初看着它那…

信息的Raid存储方式,更安全的保障,更花钱的保障!

raid0 就是把多个(最少2个)硬盘合并成1个逻辑盘使用,数据读写时对各硬盘同时操作,不同硬盘写入不同数据,速度快。  raid1就是同时对2个硬盘读写(同样的数据)。强调数据的安全性。比较浪费。 …

Java调试器和超时

在代码中存在超时的情况下如何使用调试器。 我的调试器王国! 因此,您一直忙于编写一个项目,一切顺利,直到出现错误为止。 您可以进入开发人员的工具箱,然后拔出调试器。 很棒–您可以设置断点,可以在发生异…

【题解】整理书本

题目描述 小A想把他满屋子的书整理一下。书本分成若干堆。每一堆的书本都有质量w和价值v。小A的任务是将所有书合成一堆。因为小A认为合并i,j两堆的书所需要的力为w[i]-v[i]w[j]-v[j]。合并后的书堆的质量和价值均为合并前两堆书的质量和价值的总和。也就是说&#…

C#正则表达式编程(二):Regex类用法

上一篇讲述了在C#中有关正则表达式的类之间的关系,以及它们的方法,这一篇主要是将Regex这个类的用法的,关于Match及MatchCollection类会在下一篇讲到。对于正则表达式的应用,基本上可以分为验证、提取、分割和替换。仅仅利用Regex…

浏览器记住密码的自动填充Input问题完美解决方案

1、input 前from和input占位隐藏 <form style"width:0;height:0;display:none;"><input type"password" /></form><input type"password" style"width:0;height:0;display:none;" /> 2、input autocomplete&…

Java数字格式

当我看到其他人编写不必要的Java代码并且由于缺乏对已经提供所需功能的JDK类的了解而编写了不必要的Java代码时&#xff0c;我会想到很多次。 这样的一个例子是时间相关的常量的使用硬编码值的写入&#xff0c;如60 &#xff0c; 24 &#xff0c; 1440 &#xff0c;和86400时TI…