JS高级——深入剖析函数中的this指向问题

一、this到底指向什么呢?

我们先说一个最简单的,this在全局作用域下指向什么?

  • 这个问题非常容易回答,在浏览器中测试就是指向window
    在这里插入图片描述

但是,开发中很少直接在全局作用于下去使用this,通常都是在函数中使用。

  • 所有的函数在被调用时,都会创建一个执行上下文:
  • 这个上下文中记录着函数的调用栈、AO对象等;
  • this也是其中的一条记录;

定义一个函数,我们采用三种不同的方式对它进行调用,它产生了三种不同的结果:
在这里插入图片描述

这个的案例可以给我们什么样的启示呢?

  1. 函数在调用时,JavaScript会默认给this绑定一个值;
  2. this的绑定和定义的位置(编写的位置)没有关系;
  3. this的绑定和调用方式以及调用的位置有关系;
  4. this是在运行时被绑定的;

this到底是怎么样的绑定规则呢?

  • 绑定一:默认绑定;
  • 绑定二:隐式绑定;
  • 绑定三:显示绑定;
  • 绑定四:new绑定;

二、规则一:默认绑定

什么情况下使用默认绑定呢?独立函数调用。

  • 独立的函数调用我们可以理解成函数没有被绑定到某个对象上进行调用;
    在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

三、规则二:隐式绑定

另外一种比较常见的调用方式是通过某个对象进行调用的:

  • 也就是它的调用位置中,是通过某个对象发起的函数调用。
    在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

四、规则三:显示绑定

隐式绑定有一个前提条件:

  • 必须在调用的对象内部有一个对函数的引用(比如一个属性);
  • 如果没有这样的引用,在进行调用时,会报找不到该函数的错误;
  • 正是通过这个引用,间接的将this绑定到了这个对象上;

如果我们不希望在 对象内部 包含这个函数的引用,同时又希望在这个对象上进行强制调用,该怎么做呢?

  • JavaScript所有的函数都可以使用call和apply方法(这个和Prototype有关)。
    call和apply方法的区别其实非常简单,第一个参数是相同的,后面的参数:apply为数组,call为参数列表;
  • 这两个函数的第一个参数都要求是一个对象,这个对象的作用是什么呢?就是给this准备的。
  • 在调用这个函数时,会将this绑定到这个传入的对象上。
  • 因为上面的过程,我们明确的绑定了this指向的对象,所以称之为 显示绑定

通过call或者apply绑定this对象:
在这里插入图片描述
如果我们希望一个函数总是显示的绑定到一个对象上,可以怎么做呢?
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

五、内置函数的绑定思考

有些时候,我们会调用一些JavaScript的内置函数,或者一些第三方库中的内置函数。

  • 这些内置函数会要求我们传入另外一个函数;
  • 我们自己并不会显示的调用这些函数,而且JavaScript内部或者第三方库内部会帮助我们执行;
  • 这些函数中的this又是如何绑定的呢?

setTimeout、数组的forEach、div的点击:
在这里插入图片描述
在这里插入图片描述
注意:forEach()第二个参数可以绑定this
在这里插入图片描述
在这里插入图片描述

六、规则四:new绑定

在这里插入图片描述

在这里插入图片描述

七、规则优先级

学习了四条规则,接下来开发中我们只需要去查找函数的调用应用了哪条规则即可,但是如果一个函数调用位置应用了多条规则,优先级谁更高呢?

1.默认规则的优先级最低

  • 毫无疑问,默认规则的优先级是最低的,因为存在其他规则时,就会通过其他规则的方式来绑定this

2.显示绑定优先级高于隐式绑定
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.new绑定优先级高于隐式绑定
在这里插入图片描述

4.new绑定优先级高于bind

  • new绑定和call、apply是不允许同时使用的,所以不存在谁的优先级更高
  • new绑定可以和bind一起使用,new绑定优先级更高
    在这里插入图片描述

八、this规则之外 – 忽略显示绑定

我们讲到的规则已经足以应付平时的开发,但是总有一些语法,超出了我们的规则之外。(神话故事和动漫中总是有类似这样的人物)

如果在显示绑定中,我们传入一个null或者undefined,那么这个显示绑定会被忽略,使用默认规则:
在这里插入图片描述

九、this规则之外 - 间接函数引用

另外一种情况,创建一个函数的 间接引用,这种情况使用默认绑定规则。

  • 赋值表达式(obj2.foo = obj1.foo)的结果是foo函数;
  • foo函数被直接调用,那么是默认绑定;
    在这里插入图片描述

十、箭头函数 arrow function

箭头函数是ES6之后增加的一种编写函数的方法,并且它比函数表达式要更加简洁:

  • 箭头函数不会绑定this、arguments属性;
  • 箭头函数不能作为构造函数来使用(不能和new一起来使用,会抛出错误);

箭头函数如何编写呢?

  • (): 函数的参数
  • {}: 函数的执行体

在这里插入图片描述

十一、箭头函数的编写优化

在这里插入图片描述

十二、this规则之外 – ES6箭头函数

箭头函数不使用this的四种标准规则(也就是不绑定this),而是根据外层作用域来决定this。

我们来看一个模拟网络请求的案例:

  • 这里我使用setTimeout来模拟网络请求,请求到数据后如何可以存放到data中呢?

  • 我们需要拿到obj对象,设置data;

  • 但是直接拿到的this是window,在这里插入图片描述

  • 我们需要在外层定义:var _this = this

  • 在setTimeout的回调函数中使用_this就代表了obj对象
    在这里插入图片描述
    之前的代码在ES6之前是我们最常用的方式,从ES6开始,我们会使用箭头函数:

  • 为什么在setTimeout的回调函数中可以直接使用this呢?

  • 因为箭头函数并不绑定this对象,那么this引用就会从上层作用于中找到对应的this
    在这里插入图片描述

十三、面试题

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

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

相关文章

日志测试法

/*** 写入日志*/ function write2log($content,$filenamelog) {$myfile fopen($filename.".txt", "a") or die("Unable to open file!");$txt date(Y-m-d H:i:s)."\t".$content."\r\n";fwrite($myfile, $txt);fclose($myf…

JS高级——arguments参数详解

一、认识arguments arguments 是一个 对应于 传递函数的参数 的 类数组(array-like)对象。 array-like意味着它不是一个数组类型,而是一个对象类型: 但是它却拥有数组的一些特性,比如说length,比如可以通过index索引来访问&…

php 函数有命名空间吗_解析 ThinkPHP 的命名空间

php中文网最新课程每日17点准时技术干货分享大家都知道由于PHP语法里不支持函数重载机制,如果一个应用里有两个同名的方法,怎么办呢?在Yii 框架为了避免名字重复引起问题,全部的类前边都有 C 字样,而在ThinkPHP里就引入…

JS高级——纯函数、柯里化(手写自动柯里化函数)、组合函数(手写自动组合函数)

一、理解JavaScript纯函数 函数式编程中有一个非常重要的概念叫纯函数,JavaScript符合函数式编程的范式,所以也有纯函数的概念; 在react开发中纯函数是被多次提及的;比如react中组件就被要求像是一个纯函数(为什么是…

(五)uboot移植补基础之shell

1、shell介绍:shell是操作系统的终端命令行 (1)shell可以理解为软件系统提供给用户操作的命令行界面,可以说它是人机交互的一种方式。(2)我们可以使用shell和操作系统、uboot等软件系统进行交互。具体来说就是我们通过shell给软件系统输入命令然后回车执…

三包围结构的字是什么样的_拼音带kun的字大全_50个拼音含kun的字组词

原标题:拼音带kun的字大全_50个拼音含kun的字组词1、昆(kūn),8画,上下结构,部首:曰(日)组词:昆虫(kūn chng) | 昆曲(kūn qǔ) | 昆山(kūn shān) | 昆仲(kūn zhng) | 昆吾(kūn w) | 昆仑(kūn ln) |2…

JS高级——with语句、eval函数、严格模式

一、with语句 with语句的作用:扩展一个语句的作用域链。 不建议使用with语句,因为它可能是混淆错误和兼容性问题的根源。并且,在浏览器开启严格模式下,使用with会报错: 二、eval函数 eval是一个特殊的函数&#x…

写 一个PHP脚本遇到的问题总结

在项目中,因为之前的人员,基础数据没有处理好,后面需要写一个脚本来处理这个问题,经验少,总结如下:1.在linux下直接连接跑处理MySQL数据的脚本,要用PDO的方式连接数据库,长时间在框架…

nts包如何下周 php_windows下PHP7安装方法(ts版和nts版)

1.首先到官网下载PHP的Zip安装包http://windows.php.net/download/(1)VC14 x64 Non Thread Safe (2015-Dec-17 00:17:18)(2)VC14 x64Thread Safe (2015-Dec-17 00:17:17)下载的是这两个版本,可以分别解压到C盘根目录目录存放如下NTS: C:/phpTS:C:/php-tsVC14 需要自…

JS面向对象——Object.defineProperty

一、JavaScript的面向对象 JavaScript其实支持多种编程范式的,包括函数式编程和面向对象编程: JavaScript中的对象被设计成一组属性的无序集合,像是一个哈希表,有key和value组成;key是一个标识符名称,val…

Oracle Minus关键字

Oracle Minus关键字  SQL中的MINUS关键字  SQL中有一个MINUS关键字,它运用在两个SQL语句上,它先找出第一条SQL语句所产生的结果,然后看这些结果有没有在第二个SQL语句的结果 中。如果有的话,那这一笔记录就被去除,…

极大似然函数求解_极大似然估计法的理解指南

原标题:极大似然估计法的理解指南今天讲一个在机器学习中重要的方法——极大似然估计。这是一个,能够让你拥有拟合最大盈利函数模型的估计方法。01什么是极大似然估计法极大似然估计是 1821 年由高斯提出,1912 年由费希尔完善的一种点估计方法…

json字符串和字典类型的相互转换(转载)

转自:http://www.cnblogs.com/YUTOUYUWEI/p/5585863.html 在开发过程中,有时候需要将json字符串转为字典类型,反之亦然,通常采用.Net的开源类库Newtonsoft.Json进行序列化,这里我也是采用这个,不过我更喜欢…

JS高级——对象的原型__proto__、函数的原型prototype、构造函数

一、认识构造函数 我们先理解什么是构造函数? 构造函数也称之为构造器(constructor),通常是我们在创建对象时会调用的函数;在其他面向的编程语言里面,构造函数是存在于类中的一个方法,称之为构造…

python各种数据类型的常用方法_Python之数据类型的常用方法

常用方法汇总1. int类方法汇总:变量名.to_bytes(数字,"little"\"big") # (把数字转换成bytes)# 数字表示转换后几个字节表示 little在前面,big在后面(大小端)int.from_bytes("要转换的东西","little"…

JS面向对象——原型链、通过原型链实现继承、借用构造函数实现继承

一、JavaScript原型链 在真正实现继承之前,我们先来理解一个非常重要的概念:原型链。 我们知道,从一个对象上获取属性,如果在当前对象中没有获取到就会去它的原型(__proto__)上面获取: 二、…

echart自定义动画_echarts动画效果

最近工作中碰到一个需求,要求动态展示柱状图,大概效果如下:图片是我用操作宽度模拟的效果,但是echarts以前没接触过,今天看了下文档,梯形也没做出来,想请教下大家echarts能否完成图中效果&#…

基于bootstrap框架在ie8以下,兼容媒体查询[css样式]

1 <style type"text/css">2 /*基于bootstrap框架在ie8以下&#xff0c;兼容媒体查询*/3 .row [class^"col-"] {4 float: left \9;5 }6 7 .col-xs-1, .col-sm-1, .col-md-1, .col-lg-1 {8 width: 8.33333333% \9;9 …

JS面向对象——原型式继承函数、寄生式继承函数、寄生组合式继承

一、原型式继承函数 回顾一下JavaScript想实现继承的目的&#xff1a;重复利用另外一个对象的属性和方法. 最终的目的&#xff1a;student对象的原型指向了person对象&#xff1b; 二、寄生式继承函数 寄生式(Parasitic)继承是与原型式继承紧密相关的一种思想, 并且同样由道格…

k8s pod内部容器_第三章 pod:运行于kubernetes中的容器

本章内容涵盖创建、 启动和停止 pod使用标签组织 pod 和其他资源使用特定标签对所有 pod 执行操作使用命名空间将多个 pod 分到不重叠的组中调度 pod 到指定类型的工作节点上一章 已经大致介绍了在 Kubemetes 中创建的基本组件&#xff0c;包括它们的基本功 能概述。 那么接下来…