前端 js 之 this 的绑定规则 04

news2024/10/5 21:33:06

嘿,加油😍

文章目录

  • 一、this?
  • 二、this 的指向
  • 三、默认绑定(独立函数调用)
  • 四、隐式绑定
  • 五、显式绑定 (apply call bind)
  • 六、new绑定 (后面会详细再补充)
  • 七、apply call bind 区别
  • 八、内置函数的绑定思考
  • 九、规则优先级
  • 十、说明
  • 十一、this 规则之外
    • 1. 忽略显示绑定
    • 2. ES6箭头函数


一、this?

        在其他面向对象编程中,this 一般会出现在类的方法里,但是在js中,this更灵活,无论是它出现的位置还是它代表的含义。首先this在全局里指向window, 但是,开发中很少直接在全局作用于下去使用this,通常都是在函数中使用,在之前文章里说过,当我们函数调用时,会创建一个执行上下文,这个上下文记录着函数的调用栈,AO对象,还有其他,当然还记录着一个很重要的东西,this

二、this 的指向


 	 function foo() {
        console.log(this);
      }

      // 1.调用方式一:直接调用;
      foo(); //window


      // 2.调用方式二:将foo放到一个对象中,再调用
      var obj = { name: "why", foo2: foo };
      obj.foo2(); //obj对象


      // 3.调用方式三:通过ca1l/apply调用
      foo.call("abc"); // String {"abc"子对象}
      

根据这个案例,我们可以发现

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

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

  1. 绑定一:默认绑定;
  2. 绑定二:隐式绑定;
  3. 绑定三:显示绑定;
  4. 绑定四:new绑定

三、默认绑定(独立函数调用)


当独立函数调用时,JavaScript会默认给this绑定一个值: windows

独立的函数调用我们可以理解成 函数没有被绑定到某个对象上进行调用

在这里插入图片描述

四、隐式绑定

另外一种比较常见的调用方式是通过某个对象进行调用,也就是它的调用位置中,是通过某个对象发起的函数调用。
在这里插入图片描述

五、显式绑定 (apply call bind)


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

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

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

  1. JavaScript所有的函数都可以使用call和apply方法(这个和Prototype有关)。

  2. 这两个函数的第一个参数都要求是一个对象,这个对象的作用是什么呢?就是给this准备的

  3. 在调用这个函数时,会将this绑定到这个传入的对象上。

  4. 因为上面的过程,我们明确的绑定了this指向的对象,所以称之为 显示绑定。

六、new绑定 (后面会详细再补充)


JavaScript中的函数可以当做一个类的构造函数来使用,也就是使用new关键字。

使用new关键字来调用函数是,会执行如下的操作:

  1. 首先他会创建一个全新的对象;
  2. 这个新对象会被执行prototype连接;
  3. 这个新对象会绑定到函数调用的this上(this的绑定在这个步骤完成);
  4. 如果函数没有返回其他对象,表达式会返回这个新对象;

请添加图片描述

我们通过一个new关键字调用一个函数时(构造器),这个时候this是再调用这个构造器时创建出来的对象,this=创建出来的对象,这个绑定过程也称为new绑定

七、apply call bind 区别


 	//比如夏夏有个充电宝,它可以使用charge这个充电宝给自己的手机电池phoneBattery任意充电
 	
    const xiaxia={
      name:'xiaxia',
      phoneBattery:70,
      charge:function (level){
        this.phoneBattery=level
      }
    },
    xiaxia.charge(100)


   //但是haha手机没电了,也不想买充电宝,但是它可以借xiaxia的
    const haha={
      name:'haha',
      phoneBattery:40,
    },
    xiaxia.charge.call(haha,100)


    //方便演示apply 的用法,假设充电宝必须冲两次
    const xiaxia={
      name:'xiaxia',
      phoneBattery:70,
      charge:function (level,newlevel){
        this.phoneBattery=level+newlevel
      }
    }
    
	// 如果使用 call 方式
	xiaxia.charge.call(haha,2050)
	
	// 如果使用 apply 方式
	xiaxia.charge.apply(haha,[2050])


	// bind 方式,其实是借了充电宝,但不是立即使用,而是过一会使用
	const hahaMethods=xiaxia.charge.apply(haha)
	haha.hahaMethods(20,50)
	

八、内置函数的绑定思考

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

请添加图片描述


可以通过上图发现,对于内置函数,他们的this情况,比如对于setTimeout ,他是一个独立执行,默认绑定;看第四张图,它有提示thisArg ,其实是说我们可以自己更改他的this指向,比如第三张图,如果我们传入第二个参数为obj,就把他的this执行为obj了

九、规则优先级

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

  1. 默认规则的优先级最低
    毫无疑问,默认规则的优先级是最低的,因为存在其他规则时,就会通过其他规则的方式来绑定this
  2. 显示绑定优先级高于隐式绑定 (案例一) (案例二 )
  3. new绑定优先级高于隐式绑定 (案例三)
  4. new绑定优先级高于bind ( 因为new关键字是不能和apply/call 一起使用的)
    new绑定和call、apply是不允许同时使用的,所以不存在谁的优先级更高
    new绑定可以和bind一起使用,new绑定优先级更高
	var obj={
		name:'obj'
		foo:function(){
		console.log(this)
		}
	}
	// 当这个有显示绑定(call)和隐式绑定(obj)时,发现他的this指向为 abc 
	// 说明显示绑定优先级高于隐式绑定
	obj.foo.call('abc') 
	
	var obj={
		name:'obj'
		foo:function(){
		console.log(this)
		}
	}
	// 虽然这个指向指向的是 abc,但是并不能体现 显示绑定优先级高于隐式绑定
	// 因为现在执行的是 obj 的返回的函数,绑定到abc上
	// 当foo2执行时 与obj其实是没关系的,只是执行的时候引用了而已
	var foo2 = obj.foo.bind('abc') 
	foo2()



	function foo(){
		console.log(this)
	}
	var obj={
		name:'obj'
		foo:foo.bind('aaa')
	}
	obj.foo()  //这样会更明显   指向的是aaa


	

	var obj={
		name:'obj'
		foo:function(){
		console.log(this)
		}
	}
	var f = new obj.foo()  //指向的是foo  说明new的高于隐式
	

十、说明

不管函数在什么位置声明,在内存中都是在堆内存中单独分配的空间,得到该函数地址的变量都可以对函数进行调用,所以函数中的this指向与调用位置无关,也就是谁调用就指向谁

十一、this 规则之外

1. 忽略显示绑定

apply / call /bind : 当传入 null / undefined 时, 那么这个显示绑定会被忽略,使用默认规则


	function foo(){
		console.log(this)
	}
	
	foo.apply('abc')
	foo.apply({})

	foo.apply(null)
	foo.apply(undefined)

2. ES6箭头函数

箭头函数并不绑定this对象,那么this引用就会从上层作用于中找到对应的this

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

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

相关文章

共谋工业3D视觉发展,深眸科技以自研解决方案拓宽场景应用边界

随着中国工业领域自动化程度逐渐攀升,“机器换人”这一需求进一步提升。在传统2D工业视觉易受环境光干扰、无法进一步获取物体深度信息的限制条件下,工业3D视觉凭借着更强的空间和深度感知能力,以及通过点云数据获取物体距离和三维坐标信息的…

ERR_PNPM_LINKING_FAILED Error: EPERM: operation not permitted, rename

webstorm终端pnpm报错  ERR_PNPM_LINKING_FAILED  Error: EPERM: operation not permitted, rename ’ 报错原因:powershell权限不够 解决办法:提升权限/在文件打开Powershell安装依赖

『C语言进阶』字符函数和内存函数(1)

🔥博客主页: 小羊失眠啦. 🔖系列专栏: C语言、Linux、Cpolar ❤️感谢大家点赞👍收藏⭐评论✍️ 前言 C语言中对字符和字符串的处理很是频繁,但是C语言本身是没有字符串类型的,字符串通常放在常…

【python】机器学习-K-近邻(KNN)算法

目录 一 . K-近邻算法(KNN)概述 二、KNN算法实现 三、 MATLAB实现 四、 实战 一 . K-近邻算法(KNN)概述 K-近邻算法(KNN)是一种基本的分类算法,它通过计算数据点之间的距离来进行分类。在…

【CSS】全局滚动条样式设置

直接在 App.vue 全局文件下设置滚动条样式: ::-webkit-scrollbar {width: 5px;position: absolute; } ::-webkit-scrollbar-thumb {background: #1890ff; } ::-webkit-scrollbar-track {background: #ddd; }

力扣每日一题51:N皇后问题

题目描述: 按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。 n 皇后问题 研究的是如何将 n 个皇后放置在 nn 的棋盘上,并且使皇后彼此之间不能相互攻击。 给你一个整数 n ,返回所有不同的 n 皇后问…

【51单片机外部中断控制流水灯转向】2023-10-21

缘由单片机不会搞 原理都清晰合一块成傻杯了 各位爷 用keil Vison5 还有Proteus8仿真图给出一下吧_嵌入式-CSDN问答 #include <reg52.h> unsigned char Js0; bit k0; void main() {//缘由unsigned char ls0; EA1;//总中断允许EX01;//允许外部中断0中断TH0(65536-50000)…

mysql优化之explain详解

mysql的explain&#xff08;执行计划&#xff09;用于解释sql的执行的过程&#xff0c;然后把sql的执行过程用一张表格表示出来&#xff0c;它并不真正的执行sql&#xff0c;如下图。explain能够为我们优化sql提供很好参考作用。 下面我来看下执行计划表中各个字段是什么意思 i…

【Linux】kill 命令使用

经常用kill -9 XXX 。一直在kill&#xff0c;除了kill -9 -15 &#xff0c;还能做什么&#xff1f;今天咱们一起学习一下。 kill 命令用于删除执行中的程序或工作。 kill命令 -Linux手册页 命令选项及作用 执行令 man kill 执行命令结果 参数 -l 信号&#xff0c;若果…

【吞噬星空】又被骂,罗峰杀人目无法纪,但官方留后手,增加审判戏份

Hello,小伙伴们&#xff0c;我是小郑继续为大家深度解析国漫吞噬星空资讯。 吞噬星空动画中&#xff0c;罗峰复仇的戏份&#xff0c;简直是帅翻了&#xff0c;尤其是秒杀阿特金三大巨头&#xff0c;让人看的也是相当的解气&#xff0c;相当的爽&#xff0c;一点都不拖沓&#x…

有什么站内搜索引擎优化的方法?今天跟大家分享!

在你的网站上安装站内搜索引擎对于提升用户体验和增加互动至关重要。在今天快节奏的数字世界中&#xff0c;用户希望能够快速、轻松地找到信息。通过提供站内搜索引擎&#xff0c;用户能够轻松浏览你的网站&#xff0c;帮助他们找到他们正在寻找的具体信息。接下来我将跟大家介…

浅析高校用电问题及智慧电力监管平台的构建

安科瑞 崔丽洁 摘 要&#xff1a;介绍了当前高校用电存在的问题&#xff0c;进行了原因分析&#xff0c;由此提出建立高校用电智慧监管平台。对高校用电智慧监管平台的构架进行设计&#xff0c;运用物联网技术&#xff0c;实现各回路实时自主控制&#xff0c;并细化管理权限&a…

ATA-8202射频功率放大器在超声雾化研究中的应用

超声雾化技术是一种利用高频声波能量产生微细液滴的技术&#xff0c;广泛应用于医学、生物科学、材料科学等领域。在超声雾化过程中&#xff0c;功率放大器扮演着关键的角色&#xff0c;它能提供足够的能量来驱动超声发射装置&#xff0c;并调节声波参数&#xff0c;实现有效的…

【数据结构】线性表(八)队列:顺序队列及其基本操作(初始化、判空、判满、入队、出队、存取队首元素)

文章目录 一、队列1. 定义2. 基本操作 二、顺序队列0. 顺序表1. 头文件和常量2. 队列结构体3. 队列的初始化4. 判断队列是否为空5. 判断队列是否已满6. 入队7. 出队8. 存取队首元素9. 主函数10. 代码整合 堆栈Stack 和 队列Queue是两种非常重要的数据结构&#xff0c;两者都是特…

论文浅尝 | Concept2Box:从双视图学习知识图谱的联合几何嵌入模型

笔记整理&#xff1a;张钊源&#xff0c;天津大学硕士&#xff0c;研究方向为知识图谱 链接&#xff1a;https://virtual2023.aclweb.org/paper_P4210.html 动机 知识图嵌入&#xff08;KGE&#xff09;已被广泛研究&#xff0c;用于嵌入大规模关系数据以满足许多现实世界的应用…

Spring Security总体架构介绍

参考&#xff1a;架构 :: Spring Security Reference (springdoc.cn) 一、过滤器 Spring Security 框架对 Servlet 请求的处理是基于过滤器机制。 容器会提前创建好FilterChain对每一个请求进行过滤&#xff0c;FilterChain中包含Filter 实例和 Servlet&#xff08;Spring MV…

编写后台登录滑动成功获取验证码 人机验证

vue-puzzle-vcode Vue 纯前端的拼图人机验证、右滑拼图验证 安装vue-puzzle-vcode npm install vue-puzzle-vcode --save使用vue-puzzle-vcode import Vcode from "vue-puzzle-vcode";<Vcode :show"isShow" success"onSuccess" close"…

ZooKeeper+HBase分布式集群环境搭建

安装版本&#xff1a;hadoop-2.10.1、zookeeper-3.4.12、hbase-2.3.1 一、zookeeper集群搭建与配置 1.下载zookeeper安装包 2.解压移动zookeeper 3.修改配置文件&#xff08;创建文件夹&#xff09; 4.进入conf/ 5.修改zoo.cfg文件 6.进入/usr/local/zookeeper-3.4.12/zkdat…

虚拟机与主机(win10之间的通信)

(201条消息) Ubuntu虚拟机不显示ip地址【已解决】_ubuntu没有ip_不爱赖床的懒虫的博客-CSDN博客 sudo /sbin/dhclient VMTool安装与卸载 (201条消息) ubuntu中vmtools的安装与彻底卸载_卸载vmtools_林麦安的博客-CSDN博客 (202条消息) 解决虚拟机安装 VMware Tools 灰色无法…

聊聊RocketMQ中的broker的TPS和QPS为何相差巨大,是如何统计的

这里是weihubeats,觉得文章不错可以关注公众号小奏技术&#xff0c;文章首发。拒绝营销号&#xff0c;拒绝标题党 最近在看RocketMQ的一些监控指标的时候&#xff0c;总觉得一些监控指标不太对&#xff0c;好像对不上。 所以打算研究下看看RocketMQ中的 broker TPS、broker QP…