使用 JavaScript 开发的时候,很多开发者多多少少会被 this 的指向搞蒙圈,但是实际上,关于 this 的指向,记住最核心的一句话:哪个对象调用函数,函数里面的this指向哪个对象。

下面分几种情况谈论下

1、普通函数调用

这个情况没特殊意外,就是指向全局对象-window。

let username='cn'
function fn(){
alert(this.username);//undefined
}
fn();

可能大家会困惑,为什么不是输出守候,但是在细看一看,我声明的方式是let,不会是window对象
如果输出守候,要这样写

var username='cn'
function fn(){
alert(this.username);//cn
}
fu();
//---------------
window.username='cn'
function fn(){
alert(this.username);//cn
}
fn();

//可以理解为
//window.fn();

2、对象函数调用

这个相信不难理解,就是那个函数调用,this指向哪里

window.b=2222
let obj={
a:111,
fn:function(){
alert(this.a);//111
alert(this.b);//undefined
}
}
obj.fn();

很明显,第一次就是输出obj.a,就是111。而第二次,obj没有b这个属性,所以输出undefined,因为this指向obj。

但是下面这个情况得注意

let obj1={
a:222
};
let obj2={
a:111,
fn:function(){
alert(this.a);
}
}
obj1.fn=obj2.fn;
obj1.fn();//222

这个相信也不难理解,虽然obj1.fn是从obj2.fn赋值而来,但是调用函数的是obj1,所以this指向obj1。

3、构造函数调用

let TestClass=function(){
this.name='111';
}
let subClass=new TestClass();
subClass.name='cn';
console.log(subClass.name);//cn
let subClass1=new TestClass();
console.log(subClass1.name)//111

这个也是不难理解,回忆下(new的四个步骤)就差不多了!

但是有一个坑,虽然一般不会出现,但是有必要提一下。

在构造函数里面返回一个对象,会直接返回这个对象,而不是执行构造函数后创建的对象

apply和call调用

apply和call简单来说就是会改变传入函数的this。

let obj1={
a:222
};
let obj2={
a:111,
fn:function(){
alert(this.a);
}
}
obj2.fn.call(obj1);

此时虽然是 obj2 调用方法,但是使用 了call,动态的把 this 指向到 obj1。相当于这个 obj2.fn 这个执行环境是 obj1 。apply 和 call 详细内容在下面提及。

5、箭头函数调用

首先不得不说,ES6 提供了箭头函数,增加了我们的开发效率,但是在箭头函数里面,没有 this ,箭头函数里面的 this 是继承外面的环境。

一个例子

let obj={
a:222,
fn:function(){
setTimeout(function(){console.log(this.a)})
}
};
obj.fn();//undefined

不难发现,虽然 fn() 里面的 this 是指向 obj ,但是,传给 setTimeout 的是普通函数, this 指向是 window , window 下面没有 a ,所以这里输出 undefined。

换成箭头函数

let obj={
a:222,
fn:function(){
setTimeout(()=>{console.log(this.a)});
}
};
obj.fn();//222

这次输出 222 是因为,传给 setTimeout 的是箭头函数,然后箭头函数里面没有 this ,所以要向上层作用域查找,在这个例子上, setTimeout 的上层作用域是 fn。而 fn 里面的 this 指向 obj ,所以 setTimeout 里面的箭头函数的 this ,指向 obj 。所以输出 222 。

call和apply
call 和 apply 的作用,完全一样,唯一的区别就是在参数上面。
call 接收的参数不固定,第一个参数是函数体内 this 的指向,第二个参数以下是依次传入的参数。
apply接收两个参数,第一个参数也是函数体内 this 的指向。第二个参数是一个集合对象(数组或者类数组)

let fn=function(a,b,c){
console.log(a,b,c);
}
let arr=[1,2,3];

如上面这个例子

let obj1={
a:222
};
let obj2={
a:111,
fn:function(){
alert(this.a);
}
}
obj2.fn.call(obj1);

call 和 apply 两个主要用途就是

1.改变 this 的指向(把 this 从 obj2 指向到 obj1 )

2.方法借用( obj1 没有 fn ,只是借用 obj2 方法)

原文:https://blog.csdn.net/weixin_37722222/article/details/81625826

this 的指向的更多相关文章

  1. C语言中 指向函数的指针 简介

    引子:在学习CPrimerPlus的第十四章的14.13节中,遇到了如下三行文字,是有关指向函数的指针的,把我搞晕了. char * fump(); //返回指向char的指针的函数 char (* ...

  2. JS this指向

    正常模式 在正常模式下独立函数的的 this 指向 undefined 或 window. <script type="text/javascript"> functi ...

  3. java多态性,父类引用指向子类对象

    父类引用指向子类对象指的是: 例如父类Animal,子类Cat,Dog.其中Animal可以是类也可以是接口,Cat和Dog是继承或实现Animal的子类. Animal animal = new C ...

  4. 【javascript 技巧】谈谈setTimeout的作用域以及this的指向问题

    setTimeout的用法详见:http://www.w3school.com.cn/htmldom/met_win_settimeout.asp 是的,setTimeout的常见用法是让某个方法延迟 ...

  5. what's this? 浅谈js中this的指向问题

    刚刚学习js的朋友可能和我一样,看到代码中的this总是一脸懵逼,不知道this到底指向谁.经过一段时间的了解,我想跟大家分享下自己的理解. 何时出现this 函数在调用的时候,会自动获得两个特殊变量 ...

  6. EC笔记,第二部分:10.让=返回指向*this的引用

    Effective C++ 学习笔记 10 让=返回指向*this的引用 Table of Contents 1. 原因 2. 建议:在没有充分理由标新立异前,最好的做法是遵从传统. –by SkyF ...

  7. JavaScript中this指针指向的彻底理解

    this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象 这一点与函数中自由变量Action-varibal不同 var ...

  8. JavaScript中this指向的简单理解

    首先必须要说的是,this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象(这句话有些问题,后面会解释为什么会有问题,虽然 ...

  9. 12-返回指针的函数&&指向函数的指针

    前言 接下来我只讲指针的最常见用法,比如这一章的内容----返回指针的函数 与 指向函数的指针   一.返回指针的函数 指针也是C语言中的一种数据类型,因此一个函数的返回值肯定可以是指针类型的. 返回 ...

  10. 彻底理解js中this的指向,不必硬背。

    首先必须要说的是,this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象(这句话有些问题,后面会解释为什么会有问题,虽然 ...

随机推荐

  1. Python全栈之路----常用模块----软件开发目录规范

    目录基本内容 log  #日志目录 conf  #配置目录 core/luffycity  #程序核心代码目录  #luffycity 是项目名,建议用小写 libs/modules  #内置模块 d ...

  2. LeetCode 136. Single Number C++ 结题报告

    136. Single Number -- Easy 解答 相同的数,XOR 等于 0,所以,将所有的数字 XOR 就可以得到只出现一次的数 class Solution { public: int ...

  3. 关于crontab

    crontab是一个linux系统自带的定时执行任务的功能,有两种方法可以实现 1: 使用命令 crontab -e 然后直接编辑定时脚本,实际是编辑/var/spool/cron 目录下,一个和用户 ...

  4. JVM垃圾回收机制之对象回收算法

    前言 在前面的文章中,介绍了JVM内存模型分为:堆区.虚拟机栈.方法区.本地方法区和程序计数器,其中堆区是JVM中最大的一块内存区域,在Java中的所有对象实例都保存在此区域,它能被所有线程共享. 在 ...

  5. PyCharm设置仿sublime配色__Py版本2018.3.5

    效果图: 导出settings 模板为: 1.https://files.cnblogs.com/files/xier/PyCharm_settings.zip 2.https://files.cnb ...

  6. webpack 配置别名,解决 import 时路径查找麻烦的问题

    在编写代码时,使用 import 导入别的文件,可能会遇到查找路径麻烦的问题 比如这里的 ../../ 还要去思考多少个 ../ 那么可以在 webpack 中,将 src 目录设置一个别名,方便文件 ...

  7. Git学习之第一次使用PR

    发起PR的流程 1.Fork想要pr的项目,在自己的仓库里建立一个相同的项目. 2.Clone我们Fork的项目,在本地建立一个项目,方便修改. 3.将修改后的本地项目上传到github上. 4.向原 ...

  8. 電腦清理緩存bat文件源碼

    @echo off echo 正在清除系統垃圾文件,請稍等 ...... del /f /s /q %systemdrive%\*.tmp del /f /s /q %systemdrive%\*._ ...

  9. pip安装报错 解决办法

    安装库时报错:Could not fetch URL https://pypi.python.org/simple/wheel/: 解决办法:  pip --trusted-host pypi.pyt ...

  10. 通过ZipKin整理调用链路

    缘由 公司使用的是Docker+微服务,服务拆分差不多41个了,然后过完年来就接到这个需求,把指定业务功能的业务基线整理出来,比如,登录这个操作会经过哪些微服务,把登录这个操作的链条列出来,从api- ...